Read first
async and await are a nicer way to write promise chains. The code reads like normal step-by-step
code, but it does not block the thread.
How it works
- An
asyncfunction always returns a promise.return 5fulfills it with 5;throwrejects it. - The body runs synchronously until the first
await. Then the function pauses, the caller continues, and the rest of the body is scheduled as a microtask once the awaited value is ready. awaiton something that isn’t a promise just wraps it in a resolved promise.- Errors: use
try / catcharoundawait, exactly like synchronous code. - In ES modules,
awaitalso works at the top level.
Sequential vs parallel
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
async function sequential() {
const t = Date.now();
await wait(100);
await wait(100);
return Date.now() - t; // about 200 ms
}
async function parallel() {
const t = Date.now();
await Promise.all([wait(100), wait(100)]);
return Date.now() - t; // about 100 ms
}
sequential().then((ms) => console.log('sequential >= 200:', ms >= 195));
parallel().then((ms) => console.log('parallel < 200:', ms < 195));Start independent work first, then await it together.
Traps
array.forEach(async ...)does not wait. Usefor...ofwithawait, orPromise.all(array.map(...)).- An
awaitinside a loop makes the loop sequential. Sometimes that is right (rate limits), often it is just slow. - Forgetting
awaitgives you a promise object instead of the value, and errors from it go unhandled.
Check yourself
What does calling an async function return immediately?
A pending promise. Its body has run only up to the first
await.
Two independent API calls are awaited one after the other. How do you make them faster?
Start both, then
await Promise.all([...]), so they wait at the same time.