我试图理解异步编程Node.js,但是在此代码上停滞了.
此函数在其回调中返回目录中的文件数组:
function openDir(path, callback) {
path = __dirname + path;
fs.exists(path, function (exists) {
if (exists) {
fs.readdir(path, function (err, files) {
if (err) {
throw err;
}
var result = [];
files.forEach(function (filename, index) {
result[index] = filename;
});
return callback(result);
});
}
});
}
但是,当我在.forEach中使用异步代码时,它什么也不返回:
function openDir(path, callback) {
path = __dirname + path;
fs.exists(path, function (exists) {
if (exists) {
fs.readdir(path, function (err, files) {
if (err) {
throw err;
}
var result = [];
files.forEach(function (filename, index) {
fs.stat(path + filename, function (err, stats) {
if (err) {
throw err;
}
result[index] = filename;
});
});
return callback(result);
});
}
});
}
我了解发生这种情况的原因,但不了解如何编写正确的代码.
解决方法:
其他答案可能效果很好,但是目前它们在语义上与原始代码大不相同:它们都并行执行统计信息,而不是顺序执行统计信息. forEach将启动与文件列表中的文件一样多的异步stats操作.这些操作的完成顺序可能与列表的原始顺序完全不同.这可能会严重影响错误处理逻辑.
以下方法实现了状态机,该状态机旨在异步执行统计信息,但顺序执行(未经测试):
function openDir(path, callback) {
path = __dirname + path;
fs.exists(path, function (exists) {
if (!exists)
callback(null, null); // node (err, result) convention
else {
fs.readdir(path, function (err, files) {
if (err)
callback(err, null); // node (err, result) convention
else {
var results = [];
var i = 0;
nextStep(); // process the first file (the first step)
function nextStep() {
if (i >= files.length) // no more files?
callback(null, result); // node (err, result) convention
else {
fs.stat(path + files[i], function (err, stats) {
if (err)
callback(err, null); // node (err, result) convention
else {
results[i++] = stats;
// proceed to the next file
nextStep();
}
});
}
}
}
}
}
});
});
标签:javascript,node-js,asynchronous,foreach
来源: https://codeday.me/bug/1011/1891040.html