nodejs使用foreach vs for执行顺序
我想以相同的顺序为我拥有的每个项目执行一系列事情并收集信息,然后在最后发送统计信息。
这是示例代码:
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解决问题?
回答如下:.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