[英]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.