Mastering Concurrent JavaScript: Overcome Promise.all Limits with Promise.allSettled

This article explains why Promise.all fails when any promise rejects, outlines its limitations, and demonstrates how Promise.allSettled provides a robust solution for handling multiple asynchronous operations while preserving both successful and failed results.

JavaScript
JavaScript
JavaScript
Mastering Concurrent JavaScript: Overcome Promise.all Limits with Promise.allSettled

Handling asynchronous operations has become core in JavaScript coding. As applications grow, we often need to run multiple async tasks concurrently and handle their results. Traditionally, Promise.all() is the go‑to method, but it has a fatal flaw: if any promise is rejected, the whole operation fails.

Limitations of Promise.all

Recall how Promise.all() works and its drawbacks:

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 => {
    // any rejected promise triggers this
    console.error('At least one request failed:', error);
    // we don't know which succeeded or failed
  });

The main problems are:

Any rejected promise causes the entire operation to fail.

You cannot know which operations succeeded and which failed.

You cannot retrieve results of successful operations.

In real applications we often want to continue processing successful results even when some requests fail—for example, displaying a dashboard where some components may fail to load data while others succeed.

The method Promise.allSettled() addresses all these issues. It waits for every promise to settle (fulfilled or rejected) and returns an array describing each result:

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 result with the following structure:

For a fulfilled promise: { status: 'fulfilled', value: resultValue } For a rejected promise: { status: 'rejected', reason: errorReason } This uniform structure makes result handling straightforward. In scenarios that require concurrent execution of multiple independent async operations and need complete results regardless of individual successes or failures, Promise.allSettled() is the optimal choice, enabling more resilient applications that gracefully handle inevitable errors.

JavaScriptconcurrencyAsyncPromise
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.