如何在JavaScript中使用async / await延迟数组回调?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在JavaScript中使用async / await延迟数组回调?相关的知识,希望对你有一定的参考价值。

我试图使用async await在循环中的每次迭代之间设置延迟。我有一个助手睡眠功能:

const sleep = ms => {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

这是在每个循环之间正确等待:

for (let i = 0; i < 5; i++) {
    console.log('waiting')
    await sleep(1000)
}

但是,这不是在每个循环之间等待:

[0, 1, 2, 3, 4].forEach(async () => {
    console.log('waiting')
    await sleep(1000)
});

如何修改forEach代码块以表现为常规for循环块,并在for循环的每次迭代之间有延迟?

答案

你理论上可以建立一个承诺链,使用reduce略微更漂亮,但同样的模式也可以用forEach完成:

[0, 1, 2, 3, 4].reduce(async (previous) => {
  await previous;
  console.log('waiting')
  await sleep(1000)
});

但是......为什么不使用for循环呢?

另一答案

如果您更喜欢方法而不是循环(我通常只是在美学上做),您可以引入我称为async-af的第三方模块。

除其他外,它提供了asynchronous-friendly sequential forEach

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

AsyncAF([0, 1, 2, 3, 4]).series.forEach(async () => {
  console.log('waiting');
  await sleep(1000);
});
<script src="https://unpkg.com/async-af@7.0.14/index.js"></script>
另一答案

首先,for...of是要走的路。

但是如果你很难想要一个.forEach方法,你可以这样做:

const sleep = ms => {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

/* Create your own async forEach */
Array.prototype.asyncForEach = async function asyncForEach(callback, ctx){
  const len = this.length;
  for (let i = 0; i < len; i++)
    await callback.call(ctx, this[i], i, this);
};

[0, 1, 2, 3, 4].asyncForEach(async function(n){
  await sleep(1000);
  console.log(n);
});

以上是关于如何在JavaScript中使用async / await延迟数组回调?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Javascript 中使用异步等待函数对象?

如何在 Appengine 中保留数据存储实体的版本历史记录

如何使用 jquery 或 javascript 在元素中模拟 Ctrl+A 的行为? [复制]

如何使 cProfile 仅打印重要功能?

python 来自https://stackoverflow.com/questions/23602412/only-download-a-part-of-the-document-using-pyt

如何在 JavaScript 中判断一个对象是否为空?