我已经对异步编程进行了数小时的研究,但我似乎无法掌握 Node 中的这一单一概念,所以我想知道这里是否有人可以帮助我。
我编写了以下代码示例来返回/输出一个简单的字符串,该字符串是来自对象的字符串的串联:
var itemCollection = {
item1 : [{ foo : "bar" }, { foo : "bar" }, { foo : "bar" }],
item2 : [{ foo : "bar" }, { foo : "bar" }, { foo : "bar" }],
item3 : [{ foo : "bar" }, { foo : "bar" }, { foo : "bar" }]
}
var aString = "";
for(item in itemCollection){
for (var i = 0; i < itemCollection[item].length; i++) {
var anItem = itemCollection[item][i];
//someFunctionThatDoesALongIOOperation takes an item as a param, plus a callback.
someFunctionThatDoesALongIOOperation(anItem, function(dataBackFromThisFunction){
// Do something with the data returned from this function
aString += dataBackFromThisFunction.dataToAppend;
});
};
}
console.log(aString);
因此,根据我的理解,Javascript 以外的语言将someFunctionThatDoesALongIOOperation
同步运行,并且脚本将以“阻塞模式”运行。这意味着值 aString
将以其正确的值返回/输出。
但是,由于 Node 异步运行,代码可以随时继续运行,任务可能无法按顺序完成。这是因为事件循环在 Node 中的工作方式。我想我明白了。
所以这就是我的问题所在。如果我希望像在其他语言中一样返回/输出值 aString
及其正确值,我需要对代码示例中的循环做什么?或者用更技术性的措辞来表达我的问题:使 aString
返回预期结果的正确方法是什么,以便在脚本执行完成后,当 aString
已经返回时,IO 操作(需要更长的时间来运行)不会完成?
我希望我的问题有意义,如果没有,请告诉我,我会在适当的情况下进行编辑。
谢谢
最佳答案
由于应用于每个项目的函数是异步的,因此处理它们的循环也必须是异步的(同样,使用此循环结果的函数也必须是异步的)。查看Bob Nystrom's "What Color is Your Function?"有关这一点的更多见解。
有两种方法可以做到这一点(都使用 caolan's async
library 来包装所有讨厌的回调逻辑):
一次执行一个异步操作,等待前一个操作完成后,下一个操作才能开始。这可能与传统同步循环的运行方式最相似。我们可以用
async.reduce
来做到这一点:async.reduce(itemCollection, "", function(memo, item, callback) { someFunctionThatDoesALongIOOperation(item, function(dataBackFromThisFunction) { callback(null, memo + dataBackFromThisFunction.dataToAppend); }); }, function(err, result) { var aString = result; });
当然,如果我们没有真正获得异步代码的好处并同时执行许多事情,那么拥有异步代码就没有什么意义。我们可以并行执行所有异步操作,然后在一个步骤中一次性减少所有操作。我发现如果处理每个项目需要一些长时间操作(例如网络 I/O),这非常有用,因为我们可以立即启动并等待许多请求。我们使用
async.map
实现这一目标:async.map(itemCollection, function(item, cb) { someFunctionThatDoesALongIOOperation(item, function(dataBackFromThisFunction) { cb(null, dataBackFromThisFunction.dataToAppend); }); }, function(err, results) { var aString = results.join(''); });
关于javascript - Node.js 中的异步代码和循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31600040/