我对node.js很陌生,所以我想知道如何知道何时处理所有元素让我们说:
["one", "two", "three"].forEach(function(item){
processItem(item, function(result){
console.log(result);
});
});
...现在,如果我想做一些只有在处理完所有项目后才能完成的事情,我该怎么做?
我对node.js很陌生,所以我想知道如何知道何时处理所有元素让我们说:
["one", "two", "three"].forEach(function(item){
processItem(item, function(result){
console.log(result);
});
});
...现在,如果我想做一些只有在处理完所有项目后才能完成的事情,我该怎么做?
您可以使用异步模块。简单的例子:
async.map(['one','two','three'], processItem, function(err, results){
// results[0] -> processItem('one');
// results[1] -> processItem('two');
// results[2] -> processItem('three');
});
async.map 的回调函数将在处理完所有项目时进行。但是,在 processItem 你应该小心, processItem 应该是这样的:
processItem(item, callback){
// database call or something:
db.call(myquery, function(){
callback(); // Call when async event is complete!
});
}
forEach 正在阻塞,请参阅此帖子:
JavaScript、Node.js:Array.forEach 是异步的吗?
所以要在所有项目都完成处理后调用一个函数,它可以内联完成:
["one", "two", "three"].forEach(function(item){
processItem(item, function(result){
console.log(result);
});
});
console.log('finished');
如果要处理的每个项目的 io-bound 负载很高,请查看 Mustafa 推荐的模块。上面链接的帖子中还引用了一个模式。
尽管其他答案是正确的,因为 node.js 从此支持 ES6,在我看来,使用内置Promise
库会更加稳定和整洁。
你甚至不需要什么东西,Ecma 采用了Promises/A+库并将其实现为原生 Javascript。
Promise.all(["one", "two","three"].map(processItem))
.then(function (results) {
// here we got the results in the same order of array
} .catch(function (err) {
// do something with error if your function throws
}
由于在调试方面 Javascript 是一种问题严重的语言(动态类型、异步流),因此坚持使用promise
s 而不是回调将最终节省您的时间。