6

我对node.js很陌生,所以我想知道如何知道何时处理所有元素让我们说:

["one", "two", "three"].forEach(function(item){
    processItem(item, function(result){
        console.log(result);
    });
});

...现在,如果我想做一些只有在处理完所有项目后才能完成的事情,我该怎么做?

4

3 回答 3

5

您可以使用异步模块。简单的例子:

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!
   });
}
于 2012-05-27T20:35:46.663 回答
1

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 推荐的模块。上面链接的帖子中还引用了一个模式。

于 2012-05-27T22:43:30.250 回答
1

尽管其他答案是正确的,因为 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 是一种问题严重的语言(动态类型、异步流),因此坚持使用promises 而不是回调将最终节省您的时间。

于 2015-10-24T23:43:41.890 回答