/ Gists / Async/Await Tricks
On gists

Async/Await Tricks

JavaScript

index.js Raw #

/*
@url https://levelup.gitconnected.com/7-simple-async-await-tricks-for-developers-who-hate-asynchronous-javascript-fe370ac7fe72
*/

// 1. Use Promise.allSettled() for Safer Batch Processing
const results = await Promise.allSettled([
  fetchData1(),
  fetchData2(),
  fetchData3(),
]);
results.forEach(result => {
  if (result.status === 'fulfilled') {
    console.log('Success:', result.value);
  } else {
    console.error('Failed:', result.reason);
  }
});


// 2. Use Timeouts to Prevent Hanging Promises
const withTimeout = (promise, ms) =>
  Promise.race([
    promise,
    new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms)),
  ]);

try {
  const data = await withTimeout(fetchData(), 5000);
} catch (err) {
  console.error(err.message); // "Timeout" if it takes too long
}


// 3. Sequential Loops with Async/Await
const urls = ['url1', 'url2', 'url3'];
for (const url of urls) {
  const data = await fetch(url);
  console.log(data);
}


// 4. Dynamic Delays with await
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
console.log('Start');
await delay(2000); // Waits 2 seconds
console.log('End');


// 5. Always Use try...catch Inside Async Functions
async function fetchData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) throw new Error('Fetch failed');
    return await response.json();
  } catch (err) {
    console.error('Error:', err.message);
    return null;
  }
}


// 6. await Outside Loops to Batch Workloads
const urls = ['url1', 'url2', 'url3'];
const responses = await Promise.all(urls.map(url => fetch(url)));
const data = await Promise.all(responses.map(res => res.json()));
console.log(data);


// 7 ... fking yield => dont care

allSettled.js Raw #

// https://medium.com/@genildocs/advanced-javascript-promises-4-techniques-you-havent-seen-5242a0b1556e

// Traditional approach - fails completely if any promise rejects
async function fetchUserDataOld(userIds) {
  try {
    const users = await Promise.all(
      userIds.map(id => fetch(`/api/users/${id}`).then(r => r.json()))
    );
    return users;
  } catch (error) {
    // Lost all data if even one request fails
    throw new Error('Failed to fetch user data');
  }
}

// Advanced approach - handles partial failures gracefully
async function fetchUserDataAdvanced(userIds) {
  const results = await Promise.allSettled(
    userIds.map(async (id) => {
      const response = await fetch(`/api/users/${id}`);
      if (!response.ok) {
        throw new Error(`Failed to fetch user ${id}: ${response.status}`);
      }
      return { id, data: await response.json() };
    })
  );

  const successful = results
    .filter(result => result.status === 'fulfilled')
    .map(result => result.value);

  const failed = results
    .filter(result => result.status === 'rejected')
    .map((result, index) => ({
      id: userIds[index],
      error: result.reason.message
    }));

  return {
    successful,
    failed,
    totalRequested: userIds.length,
    successRate: (successful.length / userIds.length) * 100
  };
}

// Usage
const userIds = [1, 2, 3, 4, 5];
const result = await fetchUserDataAdvanced(userIds);

console.log(`Successfully loaded ${result.successful.length} users`);
console.log(`Failed to load ${result.failed.length} users`);
console.log(`Success rate: ${result.successRate.toFixed(1)}%`);

// Handle partial failures appropriately
if (result.failed.length > 0) {
  console.log('Failed requests:', result.failed);
  // Maybe retry failed requests or show partial data
}