NodeJS:for循环和promise

One*_*one 1 node.js promise

异步编程比同步编程困难得多。

使用nodeJS,我正在尝试以下操作:

for (var i = 0; i < 10; i++) {
    someFunction().then(function() {
        // Do stuff
    });
}
Run Code Online (Sandbox Code Playgroud)

但是我希望循环仅在“完成”部分完成后才能继续。

任何想法如何可以轻松实现...?

谢谢!

小智 5

为了扩展Anders的答案,这是我过去处理此问题的方式,需要等待多个承诺:

var promises = [];

for (var i = 0; i < 10; i++) {
    promises.push(someFunction().then(function() {
            // Do stuff
        })
    );
}

Q.all(promises)
.then(function() {
    // Do all the things!
})
Run Code Online (Sandbox Code Playgroud)


aar*_*sil 5

异步编程可能会令人困惑,但如果您记住诸如回调之类的事情,并且then将在稍后运行它们包含在它们中的代码块已经完成,那么大多数混乱都可以消除。

Promise 库、async模块都是为了更好地控制程序流程。这是一篇解释不同方法的好文章,通过查看同一问题的不同替代解决方案,它确实帮助我理解了事物。

其他几个答案提到了Q.all()。如果您已经有一系列承诺,这很有效。

如果您有一组值或承诺,还有另一个库可以使这更容易,称为bluebird. 它有一个被调用的方法.map(),你可以用它来启动一个带有数组的承诺链。

使用这种方法,您不需要调用异步的、返回承诺的函数,将返回的承诺存储在一个数组中,然后将该数组传递给Q.all. 它为您节省了一些步骤。

因此,假设您有一个仅包含值的数组:

var items = [0,1,2,3,4,5,6,7,8,9];

您可以执行以下操作:

Promise.map(items, function (item) {
  return performAsyncOperation(item);
}, {concurrency: n})
.then(function(allResults){
  //  'allResults' now contains an array of all
  //  the results of 'performAsyncOperation'
})
Run Code Online (Sandbox Code Playgroud)

注意:要使其按预期工作,performAsyncOperation必须返回一个承诺

另外要注意的第三个参数Promise.map(){concurrency: n}。指定此选项后,bluebird 将只允许n一次执行操作,如果您有大量项目要处理,如果它们同时启动(网络连接、文件句柄、等等)。

最后说明:这是bluebird API doc。它写得非常好,有很多例子,是探索 Promise 如何让你的生活更轻松的好方法。

希望能帮助到你!!!