Using await in loops seems intuitive until your code silently stalls or runs slower than expected. If you’ve ever wondered why your API calls run one-by-one instead of all at once, or why map() and await don’t mix the way you’d expect, grab a chair. Let’s chat.
The problem: awaiting in a for loop
Suppose you’re fetching a list of users one-by-one:
const users = [1, 2, 3]; for (const id of users) { const user = await fetchUser(id); console.log(user); }
This works, but it runs sequentially: fetchUser(2) doesn’t start until fetchUser(1) finishes. That’s fine if order matters, but it’s inefficient for independent network calls.
Don’t await inside map() unless you mean to
A common point of confusion is using await inside map() without handling the resulting promises:
const users = [1, 2, 3]; const results = users.map(async id => { const user = await fetchUser(id); return user; }); console.log(results); // [Promise, Promise, Promise] – NOT actual user data
This works in terms of syntax and behavior (it returns an array of promises), but not in the way many expect. It doesn’t wait for the promises to resolve.
To run the calls in parallel and get the final results:
... continue reading