no-await-in-loop
禁止在循环中使用 await
对可迭代对象的每个元素执行操作是一项常见任务。但是,将 await
作为每个操作的一部分执行表明程序没有充分利用 async
/await
的并行化优势。
通常,代码应该被重构为一次创建所有 Promise,然后使用 Promise.all()
获取结果。否则,每个后续操作都必须等到上一个操作完成后才能开始。
具体来说,以下函数应该像所示那样重构
async function foo(things) {
const results = [];
for (const thing of things) {
// Bad: each loop iteration is delayed until the entire asynchronous operation completes
results.push(await bar(thing));
}
return baz(results);
}
async function foo(things) {
const results = [];
for (const thing of things) {
// Good: all asynchronous operations are immediately started.
results.push(bar(thing));
}
// Now that all the asynchronous operations are running, here we wait until they all complete.
return baz(await Promise.all(results));
}
规则详情
此规则禁止在循环体中使用 await
。
示例
此规则的正确代码示例
在代码游乐场中打开
/*eslint no-await-in-loop: "error"*/
async function foo(things) {
const results = [];
for (const thing of things) {
// Good: all asynchronous operations are immediately started.
results.push(bar(thing));
}
// Now that all the asynchronous operations are running, here we wait until they all complete.
return baz(await Promise.all(results));
}
此规则的错误代码示例
在代码游乐场中打开
/*eslint no-await-in-loop: "error"*/
async function foo(things) {
const results = [];
for (const thing of things) {
// Bad: each loop iteration is delayed until the entire asynchronous operation completes
results.push();
}
return baz(results);
}
何时不使用它
在许多情况下,循环的迭代实际上并不相互独立。例如,一次迭代的输出可能用作另一次迭代的输入。或者,循环可用于重试不成功的异步操作。或者,循环可用于防止代码发送过多的并行请求。在这种情况下,在循环中使用 await
是有意义的,建议通过标准 ESLint 禁用注释禁用该规则。
版本
此规则是在 ESLint v3.12.0 中引入的。