Async/Await Patterns
Sequential vs parallel, error handling, retry, timeout
What you'll learn
Use async/await and error handling
Choose sequential vs parallel execution
Apply timeout and retry patterns
Async/Await
async function fetchUser(id) {
const res = await fetch("/api/users/" + id)
if (!res.ok) throw Error("HTTP " + res.status)
return res.json()
}
// Always returns a promise
Error Handling
// try/catch for per-op recovery
try {
return await fetchUser(id)
} catch (err) {
console.error(err)
return null
}
// .catch for fallback chains
fetchUser(id).catch((err) => {
console.error(err)
return null
})
Sequential vs Parallel
Mixed
async function dashboard(id) {
const user = await fetchUser(id) // serial
const [posts, fol] = await Promise.all([
// parallel
fetchUserPosts(user.id),
fetchFollowers(user.id),
])
return { user, posts, fol }
}
Fetch with Timeout
async function fetchWithTimeout(url, timeout = 5000) {
const ctrl = new AbortController()
const id = setTimeout(() => ctrl.abort(), timeout)
try {
return await fetch(url, { signal: ctrl.signal })
} finally {
clearTimeout(id)
}
}
Retry Pattern
async function fetchWithRetry(url, { retries = 3, delay = 1000 } = {}) {
for (let i = 0; i <= retries; i++) {
try {
const r = await fetch(url)
if (!r.ok) throw Error("HTTP " + r.status)
return await r.json()
} catch (err) {
if (i === retries) throw err
await new Promise((r) => setTimeout(r, delay * 2 ** i))
}
}
}
See It In Action
Build fetchWithRetry
Code
javascript
1async function fetchWithRetry(url, options = {}) {2const { retries = 3, delay = 1000, timeout = 5000 } = options3const controller = new AbortController()4const timeoutId = setTimeout(() => controller.abort(), timeout)5 6for (let i = 0; i <= retries; i++) {7try {8const res = await fetch(url, { ...options, signal: controller.signal })9if (!res.ok) {10if (res.status < 500 || i === retries) throw new Error(`HTTP ${res.status}`)11continue // Retry on 5xx12}13return res.json()14} catch (err) {15if (i === retries) throw err16await new Promise(r => setTimeout(r, delay * 2 ** i))17} finally {18clearTimeout(timeoutId)19}20}21}22 23// Usage: fetchWithRetry("/api/data", { retries: 2, timeout: 3000 })A robust retry wrapper: uses AbortController for timeouts, retries only 5xx responses, and applies exponential backoff between attempts. 4xx errors throw immediately.
Lesson Summary
Key Takeaways
Async functions return promises; await pauses until settlement
Sequential for dependencies; Promise.all for parallel work
AbortController for timeouts; exponential backoff for retries