gotchajavascriptMajor
async/await in Array.forEach doesn't work
Viewed 0 times
async forEachawait in loopPromise.allsequential asyncparallel asyncfor of
Problem
Using async/await inside Array.forEach() doesn't wait for the promises. forEach ignores the return value of its callback, so await inside it does nothing useful — all iterations fire simultaneously and the code after forEach runs before they complete.
Solution
Use for...of loop for sequential execution:
// Sequential — one at a time
for (const item of items) {
await processItem(item);
}
// Parallel — all at once, wait for all
await Promise.all(items.map(item => processItem(item)));
// Parallel with concurrency limit
async function mapLimit(items, limit, fn) {
const results = [];
const executing = new Set();
for (const item of items) {
const p = fn(item).then(r => { executing.delete(p); return r; });
executing.add(p);
results.push(p);
if (executing.size >= limit) await Promise.race(executing);
}
return Promise.all(results);
}
// Sequential — one at a time
for (const item of items) {
await processItem(item);
}
// Parallel — all at once, wait for all
await Promise.all(items.map(item => processItem(item)));
// Parallel with concurrency limit
async function mapLimit(items, limit, fn) {
const results = [];
const executing = new Set();
for (const item of items) {
const p = fn(item).then(r => { executing.delete(p); return r; });
executing.add(p);
results.push(p);
if (executing.size >= limit) await Promise.race(executing);
}
return Promise.all(results);
}
Why
forEach is a synchronous function that calls its callback for each element. It doesn't know about Promises or async functions. Even though the callback is async, forEach doesn't await its return value — it just calls it and moves on.
Gotchas
- for...of is sequential — each iteration waits for the previous
- Promise.all runs all in parallel — faster but may overload APIs
- map() returns an array of Promises which Promise.all can handle
- reduce with await can also be used but is harder to read
Code Snippets
async/await with arrays
const items = [1, 2, 3];
// BAD: doesn't wait
items.forEach(async (item) => {
await doSomething(item); // fires all at once!
});
console.log('done'); // runs BEFORE any doSomething finishes
// GOOD: sequential
for (const item of items) {
await doSomething(item);
}
console.log('done'); // runs AFTER all completeContext
When performing async operations on each item in an array
Revisions (0)
No revisions yet.