]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | # Disallow `await` inside of loops (no-await-in-loop) |
2 | ||
3 | Performing an operation on each element of an iterable is a common task. However, performing an | |
4 | `await` as part of each operation is an indication that the program is not taking full advantage of | |
5 | the parallelization benefits of `async`/`await`. | |
6 | ||
7 | Usually, the code should be refactored to create all the promises at once, then get access to the | |
8 | results using `Promise.all()`. Otherwise, each successive operation will not start until the | |
9 | previous one has completed. | |
10 | ||
11 | Concretely, the following function should be refactored as shown: | |
12 | ||
13 | ```js | |
14 | async function foo(things) { | |
15 | const results = []; | |
16 | for (const thing of things) { | |
17 | // Bad: each loop iteration is delayed until the entire asynchronous operation completes | |
18 | results.push(await bar(thing)); | |
19 | } | |
20 | return baz(results); | |
21 | } | |
22 | ``` | |
23 | ||
24 | ```js | |
25 | async function foo(things) { | |
26 | const results = []; | |
27 | for (const thing of things) { | |
28 | // Good: all asynchronous operations are immediately started. | |
29 | results.push(bar(thing)); | |
30 | } | |
31 | // Now that all the asynchronous operations are running, here we wait until they all complete. | |
32 | return baz(await Promise.all(results)); | |
33 | } | |
34 | ``` | |
35 | ||
36 | ## Rule Details | |
37 | ||
38 | This rule disallows the use of `await` within loop bodies. | |
39 | ||
40 | ## Examples | |
41 | ||
42 | Examples of **correct** code for this rule: | |
43 | ||
44 | ```js | |
6f036462 TL |
45 | /*eslint no-await-in-loop: "error"*/ |
46 | ||
eb39fafa DC |
47 | async function foo(things) { |
48 | const results = []; | |
49 | for (const thing of things) { | |
50 | // Good: all asynchronous operations are immediately started. | |
51 | results.push(bar(thing)); | |
52 | } | |
53 | // Now that all the asynchronous operations are running, here we wait until they all complete. | |
54 | return baz(await Promise.all(results)); | |
55 | } | |
56 | ``` | |
57 | ||
58 | Examples of **incorrect** code for this rule: | |
59 | ||
60 | ```js | |
6f036462 TL |
61 | /*eslint no-await-in-loop: "error"*/ |
62 | ||
eb39fafa DC |
63 | async function foo(things) { |
64 | const results = []; | |
65 | for (const thing of things) { | |
66 | // Bad: each loop iteration is delayed until the entire asynchronous operation completes | |
67 | results.push(await bar(thing)); | |
68 | } | |
69 | return baz(results); | |
70 | } | |
71 | ``` | |
72 | ||
73 | ## When Not To Use It | |
74 | ||
75 | In many cases the iterations of a loop are not actually independent of each-other. For example, the | |
76 | output of one iteration might be used as the input to another. Or, loops may be used to retry | |
77 | asynchronous operations that were unsuccessful. Or, loops may be used to prevent your code from sending | |
78 | an excessive amount of requests in parallel. In such cases it makes sense to use `await` within a | |
79 | loop and it is recommended to disable the rule via a standard ESLint disable comment. |