Promises, async/await, retries & timeouts
Wait for things: promises and async
Lesson 19 of 20 · 13 min · Module 6: Asynchronous programs
Loading data from a server takes time, and the page must keep working meanwhile. Promises represent a result that arrives later, and async/await lets you write such code in a readable, top-to-bottom style.
Start this lesson →Free. No installation: you write and run the code in your browser, and it is checked automatically.
By the end, you’ll be able to…
- Explain what a promise represents
- Write async functions with await and try/catch
- Combine promises with Promise.race
The idea
An async function always returns a promise. Inside it, await promise pauses until the promise settles and gives you its value, or throws its error, which try/catch can handle. Promise.race settles with whichever promise finishes first.
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
async function demo() {
console.log("start");
await wait(10);
console.log("10 ms later");
}
await demo();
01A promise is a future value
fetch(url) returns immediately with a promise. Later it is fulfilled with a response or rejected with an error. The rest of the page keeps running in the meantime.
02await reads like normal code
Inside an async function, const data = await load() pauses only that function. A rejected promise turns into a thrown error, so try/catch handles network failures the same way as other errors.
async function load() {
try {
await Promise.reject(new Error("offline"));
} catch (e) {
return "handled: " + e.message;
}
}
console.log(await load());handled: offline03return await inside try
In retry, return task() without await would hand back the rejected promise after the try block had already finished, so the catch would never run. return await keeps the error inside the try.
Your turn
async function retry(task, attempts = 3) that calls the async function task(), returns its result as soon as one call succeeds, and after attempts failures throws the last error. Write withTimeout(promise, ms) that resolves like promise, or rejects with an Error whose message is "timeout" if it takes longer than ms.What the checks look for
- retry returns the first successful result
- retry stops after a success
- retry throws the last error after all attempts
- withTimeout passes through fast results
- withTimeout rejects slow promises with "timeout"
Take this with you
async/await lets asynchronous code read top to bottom, with try/catch for failures.
Go a little further
Add a growing delay between attempts (100 ms, 200 ms, 400 ms), known as exponential backoff.