typestar

await in a loop, and other traps in JavaScript

forEach ignores async, and await inside a loop serializes everything.

const double = async (n) => {
  await new Promise((resolve) => setTimeout(resolve, 1));
  return n * 2;
};

async function main() {
  const collected = [];
  [1, 2, 3].forEach(async (n) => collected.push(await double(n)));
  console.log("forEach saw:", collected.length); // 0: nothing awaited

  const sequential = [];
  for (const n of [1, 2, 3]) {
    sequential.push(await double(n));
  }
  console.log("for-of:", sequential);

  const parallel = await Promise.all([1, 2, 3].map(double));
  console.log("map + all:", parallel);
}

main();

How it works

  1. forEach does not wait: the callback's promise is dropped.
  2. for...of with await is sequential, which may be what you want.
  3. map plus Promise.all is the parallel version.

Keywords and builtins used here

The run, in numbers

Lines
21
Characters to type
516
Tokens
160
Three-star pace
100 tpm

At the three-star pace of 100 tokens a minute, this run takes about 96 seconds.

Type this snippet

Step 4 of 4 in async and await, step 9 of 19 in Promises & async.

← Previous Next →