nodejs使用foreach vs for执行顺序

问题描述 投票:1回答:2

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

这是示例代码:

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按预期方式(因为for执行代码执行时)

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

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

node.js async-await
2个回答
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()和promises的设计模式,通过调用串行异步操作的数组进行排序。您可以在这些答案中看到该模式的示例:

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
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.