Skip to main content

How to Resolve the ESLint Error: "Unexpected await inside a loop (no-await-in-loop)" in JavaScript

The ESLint rule no-await-in-loop flags the use of await inside a loop. This error, "Unexpected await inside a loop," is designed to prevent a common performance pitfall where multiple asynchronous operations are executed sequentially when they could be run in parallel.

This guide will explain why this rule exists, show you the correct way to handle multiple promises using Promise.all(), and clarify the specific situations where it is acceptable to disable the rule.

The Core Problem: Sequential vs. Parallel Execution

The no-await-in-loop rule exists to highlight a potential performance issue. When you use await inside a loop, each iteration of the loop must wait for the asynchronous operation to complete before the next one can even begin. This is sequential execution.

Problem: imagine you need to fetch data for three different user IDs.

async function fetchUserData(userIds) {
const results = [];
for (const id of userIds) {
// ESLint Error: Unexpected `await` inside a loop.
// Each `await` pauses the loop, waiting for the fetch to complete.
const response = await fetch(`https://api.example.com/users/${id}`);
const data = await response.json();
results.push(data);
}
return results;
}
note

If each API call takes 1 second, the total time for this function will be 3 seconds, because the second fetch doesn't start until the first one is finished, and so on.

In most cases, the asynchronous operations inside a loop do not depend on each other and can be run in parallel. The Promise.all() method is the perfect tool for this. It takes an array of promises and waits for all of them to resolve concurrently.

Logic:

  1. Inside the loop, start all the asynchronous operations without await and store the pending promises in an array.
  2. After the loop, use a single await Promise.all() to wait for all the collected promises to complete.

Solution:

async function fetchUserData(userIds) {
// 1. Create an array of promises without awaiting them.
const promises = userIds.map(id =>
fetch(`https://api.example.com/users/${id}`).then(res => res.json())
);

// 2. Wait for all promises to resolve in parallel.
const results = await Promise.all(promises);

return results;
}
note

If each API call takes 1 second, the total time for this function will be approximately 1 second (the time of the longest single request), because all three fetch requests are sent at roughly the same time. This is a significant performance improvement.

When is it OK to Await in a Loop? (And How to Disable the Rule)

There is one major scenario where using await inside a loop is not only acceptable but necessary: when each iteration depends on the result of the previous one.

For example, you might need to fetch a list of item IDs, and then make a separate request for the details of each item in a specific, sequential order.

The solution is to disable the ESLint Rule:

  • If you have a valid reason for sequential execution, you can disable the ESLint rule.

Option A (Recommended): Disable for a Single Line This is the most explicit and safest way to disable the rule, as it applies only to the specific line where it's needed.

async function processSequentially(items) {
for (const item of items) {
// Tell ESLint to ignore this specific line.
// eslint-disable-next-line no-await-in-loop
const result = await processItem(item);

// The next iteration might depend on `result`.
await anotherStepThatNeeds(result);
}
}

Option B: Disable for the Entire File If your entire file is designed around this sequential logic, you can place a comment at the top.

/* eslint-disable no-await-in-loop */

// ... your file's code ...

Conclusion

The no-await-in-loop ESLint rule is a valuable performance safeguard that encourages you to run independent asynchronous operations in parallel.

  • If your loop's operations do not depend on each other, the recommended best practice is to refactor your code to use Promise.all(). This will significantly improve performance.
  • If your loop's operations must run sequentially (i.e., one iteration depends on the previous one's result), then it is safe to disable the ESLint rule for that specific line or block of code.