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
forEachdoes not wait: the callback's promise is dropped.for...ofwith await is sequential, which may be what you want.mapplusPromise.allis the parallel version.
Keywords and builtins used here
Promiseasyncawaitconstdoubleforfunctionofreturn
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.
Step 4 of 4 in async and await, step 9 of 19 in Promises & async.