如何在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 如何在 mysql 中使用 Async/Await

在 JavaScript 中,我/应该如何将 async/await 与 XMLHttpRequest 一起使用?

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

使用async属性异步加载执行JavaScript

使用async属性异步加载执行JavaScript

在 HTML 中使用JavaScript