Understanding JavaScript Promise.allSettled(): A Complete Guide

JavaScript’s Promise handling has evolved significantly over the years, and one of the most powerful additions is the Promise.allSettled() method. Unlike its cousins Promise.all() and Promise.race(), this method offers a unique approach to handling multiple promises simultaneously.

While we’ve covered Promise.all() and Promise.race() in previous articles, Promise.allSettled() deserves special attention for its distinctive ability to handle mixed promise results effectively.

Table of Contents

What is Promise.allSettled()?

Promise.allSettled() is a method that takes an iterable of promises and returns a new promise that resolves when all input promises have settled (either fulfilled or rejected). The key difference from Promise.all() is that it won’t reject if some promises fail – it waits for all promises to complete regardless of their outcome.

Syntax

Promise.allSettled(iterable)
Code language: JavaScript (javascript)

Return Value Structure

The method returns an array of objects with the following structure:

{
  status: 'fulfilled' | 'rejected',
  value?: any, // present if status is 'fulfilled'
  reason?: any // present if status is 'rejected'
}
Code language: CSS (css)

Basic Usage Example

const promises = [
  Promise.resolve(1),
  Promise.reject('Error'),
  Promise.resolve(3)
];

Promise.allSettled(promises)
  .then(results => {
    console.log(results);
  });

// Output:
// [
//   { status: 'fulfilled', value: 1 },
//   { status: 'rejected', reason: 'Error' },
//   { status: 'fulfilled', value: 3 }
// ]
Code language: JavaScript (javascript)

Real-World Use Cases

1. API Data Fetching

async function fetchUserData(users) {
  const userPromises = users.map(user => 
    fetch(`https://api.example.com/users/${user}`)
      .then(response => response.json())
  );

  const results = await Promise.allSettled(userPromises);
  
  // Process successful and failed requests separately
  const successful = results
    .filter(result => result.status === 'fulfilled')
    .map(result => result.value);
    
  const failed = results
    .filter(result => result.status === 'rejected')
    .map(result => result.reason);

  return { successful, failed };
}
Code language: JavaScript (javascript)

2. Batch Operations

async function batchProcessFiles(files) {
  const operations = files.map(file => 
    processFile(file).catch(error => ({
      file,
      error: error.message
    }))
  );

  const results = await Promise.allSettled(operations);
  return results.map(result => {
    if (result.status === 'fulfilled') {
      return { success: true, data: result.value };
    }
    return { success: false, error: result.reason };
  });
}
Code language: JavaScript (javascript)

Error Handling Best Practices

While Promise.allSettled() doesn’t reject as a whole, it’s still important to handle individual rejections properly:

async function handleBatchOperations(tasks) {
  try {
    const results = await Promise.allSettled(tasks);
    
    // Process results
    const summary = results.reduce((acc, result) => {
      if (result.status === 'fulfilled') {
        acc.succeeded++;
        acc.successResults.push(result.value);
      } else {
        acc.failed++;
        acc.errors.push(result.reason);
      }
      return acc;
    }, {
      succeeded: 0,
      failed: 0,
      successResults: [],
      errors: []
    });

    return summary;
  } catch (error) {
    // This will only catch errors in the Promise.allSettled() itself
    console.error('Fatal error in batch operation:', error);
    throw error;
  }
}
Code language: JavaScript (javascript)

Browser Compatibility

Promise.allSettled() is supported in all modern browsers, but for older browsers, you might need a polyfill. Here’s a simple one:

if (!Promise.allSettled) {
  Promise.allSettled = promises =>
    Promise.all(
      promises.map(p =>
        p
          .then(value => ({
            status: 'fulfilled',
            value
          }))
          .catch(reason => ({
            status: 'rejected',
            reason
          }))
      )
    );
}
Code language: JavaScript (javascript)

Common Pitfalls to Avoid

  1. Don’t assume all promises will succeed just because Promise.allSettled() resolves:
// Bad practice
const results = await Promise.allSettled(promises);
results.forEach(result => console.log(result.value)); // May be undefined!

// Good practice
const results = await Promise.allSettled(promises);
results.forEach(result => {
  if (result.status === 'fulfilled') {
    console.log(result.value);
  }
});
Code language: JavaScript (javascript)
  1. Don’t forget to handle memory considerations with large arrays:
// Better approach for large datasets
async function* batchProcess(promises, batchSize = 100) {
  for (let i = 0; i < promises.length; i += batchSize) {
    const batch = promises.slice(i, i + batchSize);
    const results = await Promise.allSettled(batch);
    yield results;
  }
}
Code language: JavaScript (javascript)

When to Use Promise.allSettled()

  • When you need to execute multiple independent operations and want to know the outcome of all of them
  • When handling multiple API calls where some might fail but you want to process all results
  • In scenarios where you’re performing batch operations and need to track both successes and failures
  • When implementing retry mechanisms where you want to collect all errors before deciding how to proceed

Promise.allSettled() is particularly useful in scenarios where Promise.all() would be too strict (since it fails fast on any rejection) and Promise.race() would be insufficient (since it only provides the first settled result).

Conclusion

Promise.allSettled() is a powerful addition to JavaScript’s promise handling toolkit. It provides a robust way to handle multiple asynchronous operations where you need to track both successes and failures. By understanding its unique characteristics and proper usage patterns, you can write more resilient and maintainable asynchronous code.

Consider using Promise.allSettled() when you need to:

  • Process all results regardless of success or failure
  • Implement robust error handling for batch operations
  • Track the status of multiple independent operations

For more information about JavaScript Promises, check out our guides on Promise.all() and Promise.race().

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap