Promises, async/await and the event loop
Why asynchronous code logs in the order it does, and how to write and handle promises and async functions safely.
JavaScript runs your code on a single thread. Asynchronous work such as timers and network requests is handed off, and its callbacks are queued to run later. Questions about output order are really questions about those queues.
The order of execution
- All synchronous code in the current script runs first, top to bottom.
- Then the microtask queue is emptied. Callbacks from
thenandcatch, and code after anawait, go here. - Then one task from the task queue runs, such as a
setTimeoutcallback, and the cycle repeats.
console.log("start");
setTimeout(() => console.log("timeout"), 0);
Promise.resolve().then(() => console.log("promise"));
console.log("end");
// start, end, promise, timeout
A delay of 0 does not mean immediately. It means as soon as the call stack is empty and the microtasks are done.
Promises
A promise starts as pending, then is either fulfilled with a value or rejected with a reason. Chain then for results and end with catch for errors. Promise.all waits for every promise and rejects as soon as any one rejects, while Promise.allSettled waits for all of them and reports each outcome.
async and await
An async function always returns a promise. If it returns 5, the caller receives a promise that resolves to 5. Inside it, await pauses that function until the promise settles, without blocking the rest of the page.
async function loadUser(id) {
try {
const res = await fetch("/api/users/" + id);
if (!res.ok) throw new Error("HTTP " + res.status);
return await res.json();
} catch (err) {
console.error("Could not load user", err);
return null;
}
}
Two mistakes come up often. Forgetting await leaves you holding a promise instead of data, and awaiting independent requests one by one is slower than running them together with Promise.all.
Habit to build
When you see a snippet with timers and promises, label each line as sync, microtask or task, then write the output in that order. It takes a few seconds and removes the guesswork.
More in Programming