no-await-in-loop
禁止 await
进入循环
对可迭代的每个元素执行操作是一项常见任务。但是,在每个操作中执行 await
表明程序没有充分利用 async
/await
的并行化优势。
¥Performing an operation on each element of an iterable is a common task. However, performing an
await
as part of each operation is an indication that the program is not taking full advantage of
the parallelization benefits of async
/await
.
通常,应该重构代码以一次创建所有 Promise,然后使用 Promise.all()
访问结果。否则,每个后续操作将在前一个操作完成之前不会开始。
¥Usually, the code should be refactored to create all the promises at once, then get access to the
results using Promise.all()
. Otherwise, each successive operation will not start until the
previous one has completed.
具体来说,应该重构以下函数,如下所示:
¥Concretely, the following function should be refactored as shown:
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));
}
规则详情
¥Rule Details
该规则不允许在循环体中使用 await
。
¥This rule disallows the use of await
within loop bodies.
示例
¥Examples
此规则的正确代码示例:
¥Examples of correct code for this rule:
/*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));
}
此规则的错误代码示例:
¥Examples of incorrect code for this rule:
/*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(await bar(thing));
}
return baz(results);
}
何时不使用
¥When Not To Use It
在许多情况下,循环的迭代实际上并不是相互独立的。例如,一次迭代的输出可能用作另一次迭代的输入。或者,循环可用于重试不成功的异步操作。或者,可以使用循环来防止你的代码并行发送过多的请求。在这种情况下,在循环中使用 await
是有意义的,建议通过标准 ESLint 禁用注释禁用规则。
¥In many cases the iterations of a loop are not actually independent of each-other. For example, the
output of one iteration might be used as the input to another. Or, loops may be used to retry
asynchronous operations that were unsuccessful. Or, loops may be used to prevent your code from sending
an excessive amount of requests in parallel. In such cases it makes sense to use await
within a
loop and it is recommended to disable the rule via a standard ESLint disable comment.
版本
此规则是在 ESLint v3.12.0 中引入。