Why Promise.allSettled Beats Promise.all for Robust Async JavaScript

This article explains the limitations of Promise.all, demonstrates how Promise.allSettled handles both fulfilled and rejected promises without aborting the whole operation, and shows practical code examples for building more resilient JavaScript applications.

JavaScript
JavaScript
JavaScript
Why Promise.allSettled Beats Promise.all for Robust Async JavaScript

Handling asynchronous operations has become a core part of JavaScript coding. As applications grow in complexity, we often need to run multiple async tasks concurrently and process their results. Promise.all() has long been the default method for handling concurrent promises, but it has a fatal flaw: if any promise is rejected, the entire operation fails.

Limitations of Promise.all

Let's review how Promise.all() works and its limitations:

const promises = [
  fetch('/api/users'),
  fetch('/api/products'),
  fetch('/api/orders')
];

Promise.all(promises)
  .then(results => {
    // handle all successful results
    const [users, products, orders] = results;
    // further processing
  })
  .catch(error => {
    // if any promise fails, this runs
    console.error('At least one request failed:', error);
    // but we don't know which succeeded or failed
  });

The main problems with this approach are:

Any rejected promise causes the whole operation to fail.

You cannot know which operations succeeded and which failed.

You cannot retrieve the results of successful operations.

In real applications we often want to continue processing successful results even when some operations fail—for example, displaying other dashboard components when one component's data request fails. Promise.allSettled() solves all of these issues. It waits for every promise to settle (whether fulfilled or rejected) and returns an array containing each promise's outcome:

const promises = [
  fetch('/api/users').then(r => r.json()),
  fetch('/api/products').then(r => r.json()),
  fetch('/api/orders').then(r => r.json())
];

Promise.allSettled(promises)
  .then(results => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`Promise ${index} succeeded:`, result.value);
      } else {
        console.log(`Promise ${index} failed:`, result.reason);
      }
    });
    // You can handle all successful results while knowing which failed
    const successfulData = results
      .filter(result => result.status === 'fulfilled')
      .map(result => result.value);
    // Process the successfully fetched data
    processData(successfulData);
  });

Structure of Promise.allSettled Return Value

The return value of Promise.allSettled() is an array where each element corresponds to a promise's result, with the following structure:

For a fulfilled promise: { status: 'fulfilled', value: <result> } For a rejected promise: { status: 'rejected', reason: <error> } This uniform structure makes handling results straightforward. In scenarios where multiple independent async operations need to run concurrently and you want to obtain a complete picture regardless of individual successes or failures, Promise.allSettled() is the optimal choice, enabling more resilient applications that gracefully handle inevitable errors.

frontendJavaScriptAsynchronousPromisePromise.allSettled
JavaScript
Written by

JavaScript

Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.