Q17 of 40 · JavaScript
When should you use async/await over `.then()` chains?
Short answer
Short answer: `async`/`await` makes sequential async steps read like synchronous code, improving readability and debugging (better stack traces). `.then()` chains can be cleaner for parallel fan-out. Both compile to the same underlying Promise machinery — choice is about readability.
Detail
async/await is syntactic sugar over Promises — every async function returns a Promise, and await unwraps a Promise's value, pausing execution of that function only (not the whole thread).
When async/await is better:
- Sequential steps with error handling:
try/catchis cleaner than deeply nested.catch()handlers - Debugging: stack traces show the line with
await, making the origin of an error clearer - Conditional async logic:
if (condition) { await doA(); } else { await doB(); }is unreadable with chains
When .then() is better:
- Parallel fan-out:
Promise.all([fetch(a), fetch(b)])reads more naturally than naming two variables - Composing pipelines as data that are passed to multiple consumers
Common mistake — sequential await in a loop: Using await inside .map() makes each iteration sequential. Use await Promise.all(arr.map(async item => ...)) for parallel.
// EXAMPLE
// .then() — clean for parallel
const [user, posts] = await Promise.all([
fetch("/api/user").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
]);
// async/await — clean for sequential steps with error handling
async function loginAndFetch(creds) {
try {
const loginRes = await fetch("/api/login", {
method: "POST",
body: JSON.stringify(creds),
});
if (!loginRes.ok) throw new Error("Login failed");
const { token } = await loginRes.json();
const profile = await fetch("/api/profile", {
headers: { Authorization: `Bearer ${token}` },
});
return profile.json();
} catch (err) {
console.error("Auth error:", err.message);
throw err;
}
}// MODEL ANSWER
// WHAT INTERVIEWERS LOOK FOR
// COMMON PITFALL
// Related questions
What is a Promise, and how do you handle fulfillment, rejection, and cleanup?
JavaScript
What is the difference between `Promise.all()`, `Promise.allSettled()`, `Promise.race()`, and `Promise.any()`?
JavaScript
How does JavaScript's event loop enable asynchronous programming on a single thread?
JavaScript