繁体   English   中英

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

[英]How do I delay an array callback using async/await in JavaScript?

我试图使用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循环的每次迭代之间有延迟?

理论上可以构建一个promise链,使用reduce稍微美观一些,但是同样的模式也可以用forEach完成:

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

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

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

除此之外,它还为每个提供了一个异步友好的顺序

 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循环:

 const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); (async () => { for (const _ of [0, 1, 2, 3, 4]) { console.log('waiting'); await sleep(1000); } })(); 

至于为什么 Array.prototype.forEach没有按照你期望的方式工作,请采用这种过于简化的实现( 这里更全面 ):

 const forEach = (arr, fn) => { for (let i = 0; i < arr.length; i++) { // nothing is awaiting this function call fn(arr[i], i, arr); // i is then synchronously incremented and the next function is called } // return undefined }; forEach([0, 1, 2, 3, 4], async () => { console.log('waiting'); await delay(1000); }); 

如您所见, Array.prototype.forEach在每个元素上同步调用给定的回调函数。 这就是为什么你几乎立即看到所有五个waiting日志的原因。 有关更多信息,请参阅此问题

首先, 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); }); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM