JavaScript Promise.allSettled() Method

The JavaScript Promise.allSettled() method, introduced in ES2020, is a powerful tool for handling multiple promises simultaneously. Unlike Promise.all(), which short-circuits when any promise rejects, Promise.allSettled() waits for all promises to settle, meaning they either resolve or reject. This comprehensive guide will explore everything you need to know about Promise.allSettled(), including what it is, why it is useful, where and how to use it, and when it is most beneficial.

What is the JavaScript Promise.allSettled() Method?

Promise.allSettled() is a method that takes an iterable of promises and returns a promise that resolves after all of the given promises have either resolved or rejected. The returned promise resolves to an array of objects, each describing the outcome of each promise.

Syntax

The syntax for using Promise.allSettled() is:

JavaScript
Promise.allSettled(iterable)
  .then((results) => {
    // Handle results
  });

Example

JavaScript
const promise1 = Promise.resolve('First Promise');
const promise2 = Promise.reject('Second Promise Rejected');
const promise3 = Promise.resolve('Third Promise');

Promise.allSettled([promise1, promise2, promise3])
  .then((results) => {
    console.log(results);
  });

// Output:
// [
//   { status: 'fulfilled', value: 'First Promise' },
//   { status: 'rejected', reason: 'Second Promise Rejected' },
//   { status: 'fulfilled', value: 'Third Promise' }
// ]

In this example, Promise.allSettled() returns an array of objects indicating whether each promise was fulfilled or rejected.

Why Use the JavaScript Promise.allSettled() Method?

Promise.allSettled() offers several benefits:

  1. Reliability: It ensures that you get the results of all promises, even if some of them fail.
  2. Error Handling: Allows you to handle errors individually without short-circuiting other promises.
  3. Comprehensive Results: Provides a complete picture of all promise outcomes.

Reliability Example

Without Promise.allSettled():

JavaScript
const promise1 = Promise.resolve('First Promise');
const promise2 = Promise.reject('Second Promise Rejected');
const promise3 = Promise.resolve('Third Promise');

Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results);
  })
  .catch((error) => {
    console.error('One of the promises rejected:', error);
  });

// Output: One of the promises rejected: Second Promise Rejected

With Promise.allSettled():

JavaScript
Promise.allSettled([promise1, promise2, promise3])
  .then((results) => {
    console.log(results);
  });

// Output:
// [
//   { status: 'fulfilled', value: 'First Promise' },
//   { status: 'rejected', reason: 'Second Promise Rejected' },
//   { status: 'fulfilled', value: 'Third Promise' }
// ]

Where to Use the JavaScript Promise.allSettled() Method?

Promise.allSettled() can be used in various scenarios where you need to handle multiple promises simultaneously and want to ensure all results are captured:

  1. Batch Processing: Process multiple asynchronous tasks and handle all outcomes.
  2. API Requests: Make multiple API requests and process all responses.
  3. Data Aggregation: Aggregate data from multiple sources, handling all results.

Batch Processing Example

JavaScript
const tasks = [
  new Promise((resolve) => setTimeout(() => resolve('Task 1 Complete'), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject('Task 2 Failed'), 2000)),
  new Promise((resolve) => setTimeout(() => resolve('Task 3 Complete'), 3000))
];

Promise.allSettled(tasks)
  .then((results) => {
    results.forEach((result) => console.log(result));
  });

// Output after 3 seconds:
// { status: 'fulfilled', value: 'Task 1 Complete' }
// { status: 'rejected', reason: 'Task 2 Failed' }
// { status: 'fulfilled', value: 'Task 3 Complete' }

API Requests Example

JavaScript
const apiRequests = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
  fetch('https://api.example.com/data3')
];

Promise.allSettled(apiRequests)
  .then((responses) => {
    responses.forEach((response, index) => {
      if (response.status === 'fulfilled') {
        console.log(`API ${index + 1} response:`, response.value);
      } else {
        console.error(`API ${index + 1} error:`, response.reason);
      }
    });
  });

Data Aggregation Example

JavaScript
const dataSources = [
  Promise.resolve({ source: 'Source 1', data: [1, 2, 3] }),
  Promise.reject('Source 2 Failed'),
  Promise.resolve({ source: 'Source 3', data: [4, 5, 6] })
];

Promise.allSettled(dataSources)
  .then((results) => {
    const aggregatedData = results.reduce((acc, result) => {
      if (result.status === 'fulfilled') {
        acc.push(...result.value.data);
      }
      return acc;
    }, []);
    console.log('Aggregated Data:', aggregatedData);
  });

// Output: Aggregated Data: [1, 2, 3, 4, 5, 6]

How to Use the JavaScript Promise.allSettled() Method?

Basic Usage

To use Promise.allSettled(), pass an iterable of promises and handle the results.

JavaScript
const promises = [
  Promise.resolve('Success'),
  Promise.reject('Error'),
  Promise.resolve('Another Success')
];

Promise.allSettled(promises)
  .then((results) => {
    results.forEach((result) => {
      if (result.status === 'fulfilled') {
        console.log('Fulfilled:', result.value);
      } else {
        console.log('Rejected:', result.reason);
      }
    });
  });

Using with async/await

You can use Promise.allSettled() with async/await for a cleaner syntax.

JavaScript
const promises = [
  Promise.resolve('Success'),
  Promise.reject('Error'),
  Promise.resolve('Another Success')
];

(async () => {
  const results = await Promise.allSettled(promises);
  results.forEach((result) => {
    if (result.status === 'fulfilled') {
      console.log('Fulfilled:', result.value);
    } else {
      console.log('Rejected:', result.reason);
    }
  });
})();

Handling Errors Individually

With Promise.allSettled(), you can handle errors individually without affecting the other promises.

JavaScript
const promises = [
  Promise.resolve('Success'),
  Promise.reject('Error'),
  Promise.resolve('Another Success')
];

Promise.allSettled(promises)
  .then((results) => {
    results.forEach((result) => {
      if (result.status === 'fulfilled') {
        console.log('Fulfilled:', result.value);
      } else {
        console.error('Rejected:', result.reason);
      }
    });
  });

When to Use the JavaScript Promise.allSettled() Method?

When Handling Multiple Promises

Use Promise.allSettled() when you need to handle multiple promises and ensure all outcomes are captured.

JavaScript
const tasks = [
  new Promise((resolve) => setTimeout(() => resolve('Task 1 Complete'), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject('Task 2 Failed'), 2000)),
  new Promise((resolve) => setTimeout(() => resolve('Task 3 Complete'), 3000))
];

Promise.allSettled(tasks)
  .then((results) => {
    results.forEach((result) => {
      if (result.status === 'fulfilled') {
        console.log('Fulfilled:', result.value);
      } else {
        console.error('Rejected:', result.reason);
      }
    });
  });

When Aggregating Data from Multiple Sources

Use Promise.allSettled() to aggregate data from multiple sources, ensuring all results are handled.

JavaScript
const dataSources = [
  Promise.resolve({ source: 'Source 1', data: [1, 2, 3] }),
  Promise.reject('Source 2 Failed'),
  Promise.resolve({ source: 'Source 3', data: [4, 5, 6] })
];

Promise.allSettled(dataSources)
  .then((results) => {
    const aggregatedData = results.reduce((acc, result) => {
      if (result.status === 'fulfilled') {
        acc.push(...result.value.data);
      }
      return acc;
    }, []);
    console.log('Aggregated Data:', aggregatedData);
  });

When Making Multiple API Requests

Use Promise.allSettled() to handle multiple API requests and ensure all responses are processed.

JavaScript
const apiRequests = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
  fetch('https://

api.example.com/data3')
];

Promise.allSettled(apiRequests)
  .then((responses) => {
    responses.forEach((response, index) => {
      if (response.status === 'fulfilled') {
        console.log(`API ${index + 1} response:`, response.value);
      } else {
        console.error(`API ${index + 1} error:`, response.reason);
      }
    });
  });

Combining Promise.allSettled() with Promise.all()

Use Promise.allSettled() to handle a batch of promises and then use Promise.all() to process the results further.

JavaScript
const tasks = [
  new Promise((resolve) => setTimeout(() => resolve('Task 1 Complete'), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject('Task 2 Failed'), 2000)),
  new Promise((resolve) => setTimeout(() => resolve('Task 3 Complete'), 3000))
];

Promise.allSettled(tasks)
  .then((results) => {
    const fulfilledTasks = results.filter(result => result.status === 'fulfilled');
    return Promise.all(fulfilledTasks.map(result => result.value));
  })
  .then((fulfilledResults) => {
    console.log('All fulfilled results:', fulfilledResults);
  });

Using Promise.allSettled() in React for Data Fetching

Use Promise.allSettled() in a React component to fetch data from multiple endpoints and handle all responses.

JavaScript
import React, { useEffect, useState } from 'react';

const DataFetchingComponent = () => {
  const [data, setData] = useState([]);
  const [errors, setErrors] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const endpoints = [
        'https://api.example.com/data1',
        'https://api.example.com/data2',
        'https://api.example.com/data3'
      ];

      const promises = endpoints.map((endpoint) => fetch(endpoint).then((res) => res.json()));

      const results = await Promise.allSettled(promises);
      const successfulData = [];
      const failedData = [];

      results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
          successfulData.push(result.value);
        } else {
          failedData.push(`Error fetching data from ${endpoints[index]}: ${result.reason}`);
        }
      });

      setData(successfulData);
      setErrors(failedData);
    };

    fetchData();
  }, []);

  return (
    <div>
      <h1>Fetched Data</h1>
      {data.map((item, index) => (
        <div key={index}>
          <pre>{JSON.stringify(item, null, 2)}</pre>
        </div>
      ))}
      <h1>Errors</h1>
      {errors.map((error, index) => (
        <div key={index}>
          <p>{error}</p>
        </div>
      ))}
    </div>
  );
};

export default DataFetchingComponent;

Summary

The JavaScript Promise.allSettled() method is a powerful tool for handling multiple promises and ensuring all results are captured, regardless of whether they resolve or reject. It provides a reliable way to manage asynchronous operations, handle errors individually, and aggregate data from multiple sources. By understanding and using Promise.allSettled() effectively, you can improve the robustness and readability of your code. Practice using Promise.allSettled() in various scenarios to see its full potential and enhance your JavaScript programming skills.

Leave a Reply