async / await: Asynchronous Syntax & Control FlowIntroduced in ES2017, async and await syntax provides a synchronous-looking abstraction over JavaScript Promises, eliminating .then() chains in favor of linear try...catch control flow.
async / await Execution Modelflowchart TD
AsyncFunc["async function getData()"] --> AwaitLine["const result = await fetch(url);"]
AwaitLine --> Suspend["Function Execution Paused at await"]
Suspend --> Offload["Promise resolves in background Event Loop"]
Offload --> Resume["Function Execution Resumes with unwrapped value"]
async / await Rules Reference| Keyword | Placement | Behavior |
|---|---|---|
async |
Placed before function declaration | Causes function to automatically return a Promise. |
await |
Placed before a Promise expression | Pauses async function execution until Promise resolves/rejects. |
Top-Level await |
ES2022+ at root level of ES Modules | Allows using await outside async functions in modules. |
// Demonstrating async/await sequential vs parallel execution and error handling
const fakeApiCall = (id, delayMs, shouldFail = false) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) reject(new Error(`API Error on Task #${id}`));
else resolve(`Data payload #${id}`);
}, delayMs);
});
};
// 1. Async Function with try...catch Error Handling
async function loadUserData(userId) {
try {
console.log("Fetching user data...");
const userPayload = await fakeApiCall(userId, 100);
console.log(`User Data Received: ${userPayload}`);
return userPayload;
} catch (error) {
console.error(`Caught Async Error: ${error.message}`);
return null;
} finally {
console.log("Cleaned up loader spinner.");
}
}
loadUserData(101);
// 2. Parallel Execution with Promise.all and await
async function loadDashboardParallel() {
console.time("Parallel Dashboard Fetch");
// Launch Promises concurrently in parallel!
const promise1 = fakeApiCall(1, 100);
const promise2 = fakeApiCall(2, 100);
const [res1, res2] = await Promise.all([promise1, promise2]);
console.log(`Parallel Results: "${res1}" & "${res2}"`);
console.timeEnd("Parallel Dashboard Fetch"); // ~100ms total!
}
loadDashboardParallel();
const a = await getA(); const b = await getB();). Launch them in parallel first, then await Promise.all([pA, pB]).await in try...catch: Always wrap await expressions in try...catch blocks to catch rejected Promises cleanly.async Functions Always Return Promises: A function declared with async returns a Promise. If it returns a primitive value return 42, JS automatically wraps it in Promise.resolve(42).Why is const [user, posts] = await Promise.all([getUser(), getPosts()]); faster than const user = await getUser(); const posts = await getPosts();?
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.