为什么这个片段
const firstArray = ['toto', 'toto'];
const secondArray = ['titi', 'titi'];
firstArray.forEach(async (toto, i) =>
{
await secondArray.forEach(async titi =>
{
// async code
console.log(titi, i);
});
// async code
console.log(toto, i);
});
产生以下输出:
卸下await
关键字产生预期的输出
我的猜测是它驻留在await
关键字的行为,因为,没有它,则产生的输出是预期的输出。
编辑:这是一个纯粹的琐碎问题。我想知道为什么使用的await一个foreach提供这种行为之前。有没有“具体的代码”这背后。
EDIT2:编辑片段作为意见,回答反映了我的问题的误解
我猜你想继续之前等待所有的承诺。如果应该的话,Array.prototype.reduce(...)
的组合,Array.prototype.map(...)
和Promise.all(...)
将更好地满足:
const allPromises = firstArray.reduce((accumulatedPromises, toto) => {
const secondArrayPromises = secondArray.map((titi) => {
return // some promise;
});
const firstArrayPromise = // some promise;
return accumulatedPromises.concat(secondArrayPromises, firstArrayPromise);
}, []);
const finalPromise = Promise.all(allPromises);
于是,无论是await finalPromise
如果你是一个async function
内,或使用.then(...)
。
你的外循环forEach
吐出两个函数(注意,您有async
型;异步函数自动返回一个承诺)直接上然后按顺序终于从firstArray
输出之前运行的堆栈。因此,在执行这两种功能后,你的外循环输出打印。这是forEach
循环如何与async
功能。
要使用循环使用async/await
,你想有:
async function boot() {
for(let item of list) {
await getData(); // Here getData returns a promise
}
}
boot();
另一种方法可以是使用bluebird为Promise
:
let exec = [];
await Promise.map(list => getData());
// Here Promise.map iterates over list
// and returns a list of promises which are
// then resolved using await
的forEach同步工作这意味着它不会在每次迭代的回报(在这种情况下,承诺)做任何事情,它忽略它。
如果改用:
for(let item of arrayItems)
或者一个正常的循环,你应该看到预期的结果异步工作。
以理解的关键在于await
是异步的。所以一切之后将不早于当前执行线程返回执行。因此,部分
// async code
console.log(toto);
被放置到队列,而不是立即执行。
异步/等待本质上包裹你这样的代码:
const firstArray = ['toto', 'toto'];
const secondArray = ['titi', 'titi'];
firstArray.forEach((toto,i) => new Promise((resolve)=>
{
resolve((new Promise((resolve)=>resolve(secondArray.forEach(titi => new Promise((resolve)=>
{
resolve(console.log(titi, i));
}))))).then(()=>console.log(toto,i))
);}));
现在考虑这个代码,以及(setTimeout
是几乎是一个特定的时间量之后解决的承诺):
const firstArray = ['toto', 'toto'];
const secondArray = ['titi', 'titi'];
firstArray.forEach((toto, i) =>
{
secondArray.forEach(titi =>
{
console.log(titi, i);
});
setTimeout(()=>console.log(toto, i));
});