nodejs使用foreach vs for执行顺序

时间:2017-12-25 15:27:54

标签: node.js async-await

我想为每个项目以相同的顺序执行一系列的事情并收集信息,然后在最后发送统计信息。

这是示例代码:

let listOfItems = [];
assignedItems.forEach(async (item) => {
    let id = item.myID;
    totalItemCount += await itemRepository.getItemCount(id);

    let itemDetail = await itemRepository.getDetails(id);
    listOfItems.push(item.name);
}, this);
console.log(listOfItems.length); // 0 ??

VS

let listOfItems = [];
for (let i = 0; i < assignedItems.length; i++) {
    let id = assignedItems[i].myID;
    totalItemCount += await itemRepository.getItemCount(id);

    let itemDetail = await itemRepository.getDetails(id);
    listOfItems.push(itemDetail.name);
}
console.log(listOfItems.length); // 5 as expected
使用foreach输出

:0(因为foreach稍后执行) 输出使用for:5如预期的那样(因为在写入代码执行时执行)

主要问题是:foreach是在我的console.logs之后执行的,这些日志是在foreach之后编写的,因为我想首先收集项目的所有细节,然后发送我收集的数据。

到底是怎么回事?我如何使用foreach解决问题?

2 个答案:

答案 0 :(得分:4)

.forEach()无法按照您希望的方式使用await。如果要序列化事物,只需使用for循环await

如果您在使用.forEach()时遇到问题,请解释该问题,以便我们帮助解决该问题。

.forEach()是同步的,不会await任何内容,也无法更改它。如果您希望循环的每次迭代都为await您的承诺,则必须以不同的方式循环。 for循环将在ES6中为您执行此操作(这是ES6的明确设计功能),或者您可以自定义您自己的await手动循环代码,但.forEach()不会执行它

  

到底是怎么回事?

.forEach()是同步的。它没有await你的承诺。这就是它的设计方式。

  

如何使用foreach解决问题?

你没有。如果要在继续之前等待循环的每次迭代,请使用常规for循环。这是ES6的一项功能,包含常规for循环,而不是.forEach()

仅供参考,如果您想要一个等待承诺的.forEach()类似功能,您可以使用Bluebird promise library并使用Promise.mapSeries()Promise.each()之类的内容。这些函数都寻找从它们的回调返回的promise,并且在这些promise被解析之前不执行下一次迭代。但是,array.forEach()没有内置该功能。

还有使用.reduce()的设计模式,并承诺通过调用串行异步操作的数组进行排序。您可以在这些答案中看到该模式的示例:

how to write to new files sequentially

Can Promise load multi urls in order?

iterating over promises node js

how to make synchronous http calls using promises in node.js

答案 1 :(得分:1)

请阅读这篇文章,希望你能在这里找到答案。 Here is the link