7. Promises & async/await
JavaScript · 56 pages source format
JavaScript is single-threaded but non-blocking. Promises represent future values. async/await is syntactic sugar over Promises — readable sequential async code. Promise.all for parallel, Promise.race for first-wins. Always handle rejections.
What you'll learn
- Callback → Promise mental model
- then/catch/finally
- async/await
- Promise.all / Promise.allSettled
- Error propagation
Promise basics
new Promise((resolve, reject) => ...) wraps async work. .then handles success, .catch handles failure. A Promise is pending → fulfilled or rejected once.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
delay(1000).then(() => console.log("done"))Do this now
Wrap setTimeout in a delay(ms) function returning a Promise. Chain .then to print "done" after 1 second.
async/await
async function always returns a Promise. await pauses until Promise settles. Use try/catch for errors instead of .catch chains.
async function pauseAndGreet(name) {
await delay(500)
console.log(`Hello, ${name}!`)
}Do this now
Rewrite delay chain using async/await. Write async function pauseAndGreet(name) that waits 500ms then logs greeting.
Parallel vs sequential
Sequential: await a; await b — total time = a + b. Parallel: await Promise.all([a, b]) — total time = max(a, b).
Do this now
Fetch two URLs sequentially, time it. Fetch in parallel with Promise.all, time again. Compare.
Pro tip. Do not await inside a map if tasks are independent — use Promise.all(items.map(fn)).
Error handling
Unhandled rejections crash Node and warn in browsers. Always try/catch around await or .catch on chains. Re-throw or return error states — never swallow silently.
Do this now
Write fetchWithRetry(url, retries=3) that catches failures and retries with delay.
Promise.allSettled
Unlike Promise.all, allSettled waits for all regardless of failures. Useful when partial success is acceptable.
Do this now
Fetch 3 URLs with allSettled. Log which succeeded and which failed.