Waiting for Promises with await
.then chains are flat, but they still split your code into many small functions. async and await let you write the same steps as normal code, one line after another.
Put async before a function. Inside it, await pauses that function until a promise is resolved:
const wait = ms =>
new Promise(resolve => setTimeout(resolve, ms));
async function kitchen() {
console.log("order received");
await wait(100);
console.log("cooking...");
await wait(100);
console.log("served");
}
kitchen();
Output:
order received
cooking...
served
This reads from top to bottom, like the code you wrote before this section. But the waits are real. Each await waits for its promise, just like a .then would. Most modern JavaScript code is written this way.
If the promise has a value, await gives it to you, so you can store it in a variable: const data = await getData();.
await pauses the function, not the whole program. While kitchen waits, other code can run. Here a timer prints a message after 150 ms:
const wait = ms =>
new Promise(resolve => setTimeout(resolve, ms));
async function kitchen() {
console.log("order received");
await wait(100);
console.log("cooking...");
await wait(100);
console.log("served");
}
kitchen();
setTimeout(() => console.log("waiter checks"), 150);
Output:
order received
cooking...
waiter checks
served
kitchen() started, printed its first line and paused at the first await. The program went on and scheduled the timer. The timer's message came at 150 ms, between the two steps of the kitchen. This is why one JavaScript server can serve many users at once. While one request waits, the others keep running.
Put await inside an async function. The programs in this course use require to read input, and in such a program an await outside any function stops the program with an error.
Errors work with try/catch. When an awaited promise is rejected, await throws the error. So you can catch it as you learned in the Errors section. Here cook returns a promise that is rejected, like the one in the previous lesson:
const wait = ms =>
new Promise(resolve => setTimeout(resolve, ms));
function cook() {
return wait(100).then(() => {
throw new Error("oven is broken");
});
}
async function kitchen() {
try {
await cook();
console.log("served");
} catch (err) {
console.log("problem:", err.message);
}
}
kitchen();
Output:
problem: oven is broken
In the exercise, add two await steps to the kitchen, so the waiter's message lands between cooking and serving.