What Is Async/Await?
async/await is syntactic sugar built on top of Promises. It lets you write asynchronous code that looks and behaves like synchronous code, making it far easier to read and debug.
Basic Syntax
An async function always returns a Promise. The await keyword pauses execution until the Promise resolves.
async function fetchUser() {
const response = await fetch('https://api.example.com/user/1');
const user = await response.json();
return user;
}
// Calling the async function
fetchUser().then(user => console.log(user));
Error Handling with try/catch
Always wrap await calls in try/catch blocks to handle rejections gracefully.
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch data:', error.message);
return { error: true, message: error.message };
}
}
Parallel Execution
Avoid sequential awaits when requests are independent — use Promise.all() instead.
// BAD: Sequential (slower)
async function getSequential() {
const users = await fetch('/api/users').then(r => r.json());
const posts = await fetch('/api/posts').then(r => r.json());
const comments = await fetch('/api/comments').then(r => r.json());
return { users, posts, comments };
}
// GOOD: Parallel (faster)
async function getParallel() {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json())
]);
return { users, posts, comments };
}
Promise.allSettled for Partial Success
When you want all results regardless of failures, use Promise.allSettled().
async function fetchMultiple() {
const results = await Promise.allSettled([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Request ${index} succeeded:`, result.value);
} else {
console.log(`Request ${index} failed:`, result.reason);
}
});
}
Retry with Exponential Backoff
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url);
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
}
}
}
Top-Level Await
In ES modules, you can use await at the top level without wrapping in an async function.
// module.js
const response = await fetch('/api/config');
const config = await response.json();
export default config;