JS · Async1 min read

Async Mistakes

forEach silently discards promise return values, which means your async callbacks are running but nobody's waiting on them. Use map plus Promise.all, or for...of if order matters.

forEach is bad with async

forEach is for side effects and discards return values, so it’s incompatible with async/await. For async work, either use for…of when sequencing matters, or map/flatMap plus Promise.all when you want concurrency.

JavaScript
array.forEach(async (x) => {
  await doAsync(x);
});

What actually happens:

  • forEach ignores the return value
  • async callbacks return promises…
  • …but no one captures them
  • there is nothing to await

Instead, use map/flatMap

JavaScript
const promises = array.map(async (x) => {
  await doAsync(x);
});
await Promise.all(promises);
  • map returns a new array
  • async callback returns a promise
  • Promise.all awaits those promises

for…of + await is also correct (but serial)

JavaScript
for (const x of array) {
  await doAsync(x);
}