JavaScriptAsync/Await Patterns

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)));
    }
  }
}