gotchajavascriptMajorpending
Gotcha: JavaScript async/await in forEach does not work
Viewed 0 times
forEachasyncawaitPromise.allfor-ofsequential
Error Messages
Problem
Using async/await inside Array.forEach does not wait for async operations to complete. The loop finishes before any awaits resolve.
Solution
forEach does not await promises. Use for...of or Promise.all instead:
// BAD - forEach ignores await:
const items = [1, 2, 3];
items.forEach(async (item) => {
await processItem(item); // Not awaited by forEach!
});
console.log('done'); // Runs before processing finishes
// GOOD - Sequential processing:
for (const item of items) {
await processItem(item);
}
console.log('done'); // Runs after all items processed
// GOOD - Parallel processing:
await Promise.all(items.map(item => processItem(item)));
console.log('done'); // Runs after all items processed
// GOOD - Parallel with concurrency limit:
async function mapLimit(items, limit, fn) {
const results = [];
for (let i = 0; i < items.length; i += limit) {
const chunk = items.slice(i, i + limit);
results.push(...await Promise.all(chunk.map(fn)));
}
return results;
}
// BAD - forEach ignores await:
const items = [1, 2, 3];
items.forEach(async (item) => {
await processItem(item); // Not awaited by forEach!
});
console.log('done'); // Runs before processing finishes
// GOOD - Sequential processing:
for (const item of items) {
await processItem(item);
}
console.log('done'); // Runs after all items processed
// GOOD - Parallel processing:
await Promise.all(items.map(item => processItem(item)));
console.log('done'); // Runs after all items processed
// GOOD - Parallel with concurrency limit:
async function mapLimit(items, limit, fn) {
const results = [];
for (let i = 0; i < items.length; i += limit) {
const chunk = items.slice(i, i + limit);
results.push(...await Promise.all(chunk.map(fn)));
}
return results;
}
Why
forEach calls the callback but does not await the returned promise. It was designed before async/await existed and was never updated.
Revisions (0)
No revisions yet.