等待嵌套的forEach行为

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

为什么这个片段

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);
});

产生以下输出:

output

卸下await关键字产生预期的输出

enter image description here

我的猜测是它驻留在await关键字的行为,因为,没有它,则产生的输出是预期的输出。

编辑:这是一个纯粹的琐碎问题。我想知道为什么使用的await一个foreach提供这种行为之前。有没有“具体的代码”这背后。

EDIT2:编辑片段作为意见,回答反映了我的问题的误解

javascript node.js
4个回答
0
投票

我猜你想继续之前等待所有的承诺。如果应该的话,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(...)


0
投票

你的外循环forEach吐出两个函数(注意,您有async型;异步函数自动返回一个承诺)直接上然后按顺序终于从firstArray输出之前运行的堆栈。因此,在执行这两种功能后,你的外循环输出打印。这是forEach循环如何与async功能。

要使用循环使用async/await,你想有:

async function boot() {
  for(let item of list) {
    await getData(); // Here getData returns a promise
  }
}

boot();

另一种方法可以是使用bluebirdPromise

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

0
投票

的forEach同步工作这意味着它不会在每次迭代的回报(在这种情况下,承诺)做任何事情,它忽略它。

如果改用:

for(let item of arrayItems)

或者一个正常的循环,你应该看到预期的结果异步工作。


-1
投票

以理解的关键在于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));
});
© www.soinside.com 2019 - 2024. All rights reserved.