Mastering Async/Await
Async/await is syntactic sugar built on top of Promises, making asynchronous code look and behave more like synchronous code.
Basic Syntax
async function fetchUserData(userId) {
try {
const response = await fetch(\/api/users/\${userId}\);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch user:', error);
throw error;
}
}
Best Practices
1. Always Use Error Handling
async function safeFetch(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(\HTTP error! status: \${response.status}\);
}
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
return null;
}
}
2. Use Promise.all() for Parallel Operations
// Bad - Sequential (slow)
const user = await fetchUser(id);
const posts = await fetchPosts(id);
const comments = await fetchComments(id);// Good - Parallel (fast)
const [user, posts, comments] = await Promise.all([
fetchUser(id),
fetchPosts(id),
fetchComments(id)
]);
3. Promise.allSettled for Fault Tolerance
const results = await Promise.allSettled([
fetchCriticalData(),
fetchOptionalData(),
fetchAnalytics()
]);results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(\Request \${index} succeeded:\, result.value);
} else {
console.log(\Request \${index} failed:\, result.reason);
}
});
Advanced Patterns
Retry Logic
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 * (i + 1)));
}
}
}