我想以相同的顺序为我拥有的每个项目执行一系列事情并收集信息,然后在最后发送统计信息。
这是示例代码:
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
请阅读这篇文章,希望你能在这里找到答案。 Here is the link