Nodejs fs.readdir的问题
Nodejs fs.readdir的问题
从node.js + express4 写一个自己的博客网站教程中写代码,发现获取所有文件夹下的文件,最终结果如何在外面得到呢??return 返回的不是getBlogList的返回值吧?
function getBlogList(blogDir) {
fs.readdir(blogDir, function (err, files) {
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
//split file name and generate url...
//...
//create a blogItem { title: blogTitle, url: blogUrl }
blogList.push(blogItem);
});
}
return blogList;
});
}
刚接触node,疑惑很久,请各位赐教~谢谢
从node.js + express4 写一个自己的博客网站教程中写代码,发现获取所有文件夹下的文件,最终结果如何在外面得到呢??return 返回的不是getBlogList的返回值吧?
function getBlogList(blogDir) {
fs.readdir(blogDir, function (err, files) {
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
//split file name and generate url...
//...
//create a blogItem { title: blogTitle, url: blogUrl }
blogList.push(blogItem);
});
}
return blogList;
});
}
刚接触node,疑惑很久,请各位赐教~谢谢
由于fs.readdir为异步操作,你可以使用回调函数来做:
function getBlogList(blogDir, callback) {
fs.readdir(blogDir, function (err, files) {
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
//split file name and generate url...
//...
//create a blogItem { title: blogTitle, url: blogUrl }
blogList.push(blogItem);
});
}
callback(blogList);
});
}
getBlogList的使用是这样:
getBlogList('<BLOG_DIR>', function(list) {
// You can get blog list here.
});
当然可以。你遇到的问题主要是因为 fs.readdir
是一个异步函数,而你在尝试以同步的方式处理它的返回值。在 Node.js 中,异步函数不会直接返回值,而是通过回调函数来传递结果。因此,你需要使用回调函数或者 Promises 来处理这种异步操作。
下面是一个修改后的示例,展示了如何正确地处理 fs.readdir
的结果,并将其传递给外部函数:
使用回调函数
const fs = require('fs');
function getBlogList(blogDir, callback) {
fs.readdir(blogDir, function (err, files) {
if (err) {
return callback(err); // 如果有错误,将错误传递给回调函数
}
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
// 假设我们根据文件名生成标题和 URL
const blogTitle = filename.replace('.md', '');
const blogUrl = `/blog/${blogTitle}`;
// 创建一个包含标题和 URL 的对象
const blogItem = { title: blogTitle, url: blogUrl };
blogList.push(blogItem);
});
}
callback(null, blogList); // 将结果传递给回调函数
});
}
// 调用 getBlogList 并传递回调函数
getBlogList('./blogs', function (err, blogList) {
if (err) {
console.error('Error:', err);
return;
}
console.log('Blog List:', blogList);
});
使用 Promises
如果你更喜欢使用 Promises,可以使用 fs.promises.readdir
方法,该方法返回一个 Promise,可以在 .then
方法中处理结果。
const fs = require('fs').promises;
async function getBlogList(blogDir) {
try {
const files = await fs.readdir(blogDir);
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
// 假设我们根据文件名生成标题和 URL
const blogTitle = filename.replace('.md', '');
const blogUrl = `/blog/${blogTitle}`;
// 创建一个包含标题和 URL 的对象
const blogItem = { title: blogTitle, url: blogUrl };
blogList.push(blogItem);
});
}
return blogList; // 返回 Promise 的结果
} catch (err) {
throw err; // 抛出错误以便外部处理
}
}
// 调用 getBlogList 并使用 .then 和 .catch 处理结果
getBlogList('./blogs')
.then(blogList => {
console.log('Blog List:', blogList);
})
.catch(err => {
console.error('Error:', err);
});
在这两个示例中,我们都确保了异步操作的结果能够正确地传递到外部函数。希望这能帮助你理解如何处理异步操作并获取正确的结果。
function getBlogList(blogDir, callback) {
fs.readdir(blogDir, function (err, files) {
if(err) return callback(err);
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
//split file name and generate url...
//...
//create a blogItem { title: blogTitle, url: blogUrl }
blogList.push(blogItem);
});
}
return callback(null, blogList);
});
}
getBlogList('dir', function(err, list){
handle(list);
});
现在我终于知道为什么async不够用,需要promise,我也知道为什么promise也不够用了,要generator,我也知道generator为什么不够用了,要fibjs,都是异步惹得祸啊。
楼主如果需要遍历目录内的目录的话,恐怕还要加点代码。给个参考dir 看看着那一层层的回调,有的人深恶痛绝,有的却是很喜欢的,我就是喜欢的那种人。
顺便求高人用promise也实现一个,让我顺便学习一下promise的用法,回调其实倒不可怕,可怕的是那些一层又一层的错误处理,promise只懂皮毛,还望大神来答疑。
[@zhengchubo](/user/zhengchubo) 谢谢啊~解决啦
[@coordcn](/user/coordcn) 嘿嘿 学习啦~~谢谢
var Promise = require("bluebird"),
readDir = Promise.promisify(require("fs").readdir);
readDir(blogDir)
.then(function(files){
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
//split file name and generate url...
//...
//create a blogItem { title: blogTitle, url: blogUrl }
blogList.push(blogItem);
});
}
return blogList;
})
.then(handle)
.catch(SyntaxError,function(e){
//File error
})
.catch(function(e){
//any other error
})
太棒了,遇到了同样的问题,谢谢:)
我去,踩到盗洞了。还以为 2 楼在开嘲讽。6楼支持你直接 fs.readdirSync
在Node.js中,fs.readdir
是一个异步函数,这意味着它不会立即返回结果。因此,直接使用 return
语句无法将结果返回到调用者。为了处理这种情况,你需要使用回调函数来传递结果。
以下是修改后的示例代码:
const fs = require('fs');
function getBlogList(blogDir, callback) {
fs.readdir(blogDir, function (err, files) {
if (err) {
return callback(err);
}
var blogList = [];
if (files && files.length) {
files.forEach(function (filename) {
// 假设这里生成了 blogItem 对象
const blogItem = {
title: filename,
url: `/blog/${filename}`
};
blogList.push(blogItem);
});
}
callback(null, blogList);
});
}
// 调用 getBlogList 函数,并提供一个回调函数来处理结果
getBlogList('./blogs', function (err, blogList) {
if (err) {
console.error('Error:', err);
return;
}
console.log('Blog List:', blogList);
});
解释
- 异步操作:
fs.readdir
是一个异步操作,所以不能简单地用return
返回结果。 - 回调函数:通过传递一个回调函数给
getBlogList
,可以在读取文件后执行该回调函数,并传入结果。 - 错误处理:如果读取文件时发生错误,会通过回调函数的第一个参数(通常是错误对象)返回错误信息。
- 数据处理:在
callback
中传递处理后的blogList
数据。
这样可以确保在 fs.readdir
完成后正确地处理结果。