JavaScriptadvanced 9 min
Write code that waits for slow things without freezing the page, using promises and async functions.
What a promise is, how async and await make waiting code easy to read, and how to run several tasks at once with Promise.all.
Fetching data, reading files and timers all take time. If JavaScript stopped everything to wait, pages would freeze. Asynchronous code lets the program keep working and come back when the result is ready.
Normally code runs line by line. A slow task, like a network request, is started and JavaScript moves on. It needs a way to hand you the result later. That is a promise: an object that represents a value that will exist in the future. A promise is pending, then either fulfilled (with a value) or rejected (with an error).
async / await is the readable way to use promises:
async before a function. It now always returns a promise.await somePromise pauses that function until the promise settles, and gives you the value.try / catch around await to handle rejections.setTimeout(fn, ms) runs code after a delay and is the classic async example.
Promise.all([a, b]) runs several promises at the same time and waits for all of them.
wait returns a promise that resolves with a value after a delay.main is async. It prints start, then awaits the first promise for 300ms and prints first.Promise.all starts two waits at once. They take about 200ms in total, not 300ms. The results come back in order: second third.await, so catch runs and prints caught: something failed.end.Change the delays and check what order the output appears in. Then replace Promise.all with two separate await lines and compare the total time.
await, so you get a pending promise instead of the value.await in a normal function. It only works inside async functions (or at the top level of modules).Promise.all.async / await makes asynchronous code read like normal code.Promise.all runs tasks together; try / catch handles failures.Next: using this to fetch data from a server.
function wait(ms, value) {
return new Promise((resolve) => setTimeout(() => resolve(value), ms));
}
async function main() {
console.log("start");
const a = await wait(300, "first");
console.log(a);
const [b, c] = await Promise.all([wait(200, "second"), wait(100, "third")]);
console.log(b, c);
try {
await Promise.reject(new Error("something failed"));
} catch (err) {
console.log("caught:", err.message);
}
console.log("end");
}
main();