等待每个回调

时间:2018-09-27 06:41:18

标签: javascript asynchronous async-await

我遇到一个问题,我需要等待一次foreach循环返回。我尝试将await放在某些地方,并尝试使用Promise,但无法正常工作。请看下面的代码,以更好地理解我的问题。

arr = [1, 2, 3];

MyFunction = async function() {
    arr.forEach(async element => {
        setTimeout(() => {
            console.log(element);
        }, 1000); 
    });
    console.log('done');
}

MyFunction();

使用此代码,您将得到:

done
1
2
3

我如何使用await或类似的东西使它出来:

1
2
3
done

2 个答案:

答案 0 :(得分:2)

签出Promise.all()。本质上,在数组上使用.map()可以将其变成一个承诺数组,然后等待所有承诺,然后继续执行。

arr = [1, 2, 3];

MyFunction = async function() {
    var promises = arr.map(element => {
        return new Promise((resolve) => {
          setTimeout(() => {
              console.log(element);
              resolve();
          }, 1000); 
        });
    });
    
    await Promise.all(promises);
    console.log('done');
}

MyFunction();

答案 1 :(得分:0)

使用asyncawait不会神奇地将基于回调的异步函数转换为可以等待的基于Promise的承诺。因此,您需要使基于回调的asnyc代码更加合理:

return new Promise(resolve => {
  setTimeout(() => {
    console.log(element);
    resolve()
  }, 1000);
})

arr.forEach将破坏Promise链,因为您没有保存在箭头函数中创建的Promise,从那时起您就不能等待它们。因此,您需要使用mapPromise.all

arr = [1, 2, 3];

MyFunction = async function() {
  await Promise.all(arr.map(async element => {
    return new Promise(resolve => {
      setTimeout(() => {
        console.log(element);
        resolve()
      }, 1000);
    })
  }));
  console.log('done');
}

MyFunction();

如果需要按顺序完成异步任务,则可以使用常规的for循环。

arr = [1, 2, 3];

MyFunction = async function() {
  for( let element of arr) {
    await new Promise(resolve => {
      setTimeout(() => {
        console.log(element);
        resolve()
      }, 1000);
    })
  }
  console.log('done');
}

MyFunction();