Stop using Promise.all() in JavaScript

What are Promises in JavaScript?

If you stumbled upon this article, you’re probably already familiar with promises. But for those new to JavaScript, let’s explain it in detail. Essentially, a Promise object represents the eventual completion or failure of an asynchronous operation. Interestingly, when a promiseis created, its value may not be immediately available.

const promise = new  Promise ( ( resolve, reject ) => {  
   // Some asynchronous operations   
  if ( /* Operation successful */ ) {    
     resolve (result);  
  } else {    
    reject(error);  
  }
});

They have 3 states:

  • Pending : This is the initial state and is neither implemented nor rejected.
  • Fulfilled : The state when a promise completes successfully and produces a value.
  • Rejected : The state when an error occurs and the operation in the promise was unsuccessful.

Once the promise is resolved, you can use .then()to handle the result and to .catch()manage any errors that occurred during its execution.

promise  
  .then( result => {    
     console . log ( 'Success:' , result);  
  })  
  .catch( error => {    
     console .error( 'Error: ' , error);  
  });

Understanding Promise.all()

When working with multiple at the same time promises, you can take advantage of the built-in Promise.all([])methods. This method accepts an array of promises and returns a unified promise. The key is that promisesthis combined will only be solved if all of the inputs have been successfully solved promise. If one of them fails, the whole promiseis rejected. Here is an example:

const promise1 = fetch('https://api.example.com/data1');
const promise2 = fetch('https://api.example.com/data2');
const promise3 = fetch('https://api.example.com/data3');

Promise.all([promise1, promise2, promise3])  
  .then( values ​​=> {    
     console . log ( 'All data obtained: ' , values);  
  })  
  .catch( error => {    
     console .error( 'An error occurred: ' , error);  
  });

This approach is typically used when there are multiple related asynchronous tasks and their work depends on each other, so we want all of the asynchronous tasks to succeed before continuing with code execution.

Reveal Promise.allSettled()

Use is similar Promise.allSettled([])to Promise.all([]), but differs in that it waits for all inputs promisesto complete or be rejected, and returns promisean array of objects describing each result.

const promise1 = Promise . resolve ( 'Success 1' );
 const promise2 = Promise . reject ( 'Error 2' );
 const promise3 = Promise . resolve ( 'Success 3' );

Promise.allSettled([promise1, promise2, promise3])
  .then(results => {
    results. forEach ( result => {
       if (result. status === 'fulfilled' ) {
         console . log ( 'Successfully obtained value: ' , result. value );
      } else {
         console . error ( 'Rejected for reason: ' , result. reason );
      }
    });
 });

//Output 
// Successfully obtained value: Success 1 
// Rejected due to reason: Error 2 
// Successfully obtained value: Success 3

It is usually used to handle asynchronous operations that do not depend on each other and you want to know the result of each one.

Why Promise.allSettled() is better

Overall, using Promise.allSettled()instead Promise.all()has its advantages in most common situations:

Comprehensive results information

If any one of the promises is rejected, Promise.all()the immediate rejection may make it promisesdifficult to determine the status of the others, especially if the others promisesresolve successfully. Using Promise.allSettled([])gives you a complete picture of your results.

Elegant error handling

Promise.all()The “fail fast” approach may be limited if you want to continue while one of them fails, while Promise.allSettled()allowing you to handle promisethe results of each individually.

Batch operation

When dealing with batch operations, where individual operations are independent, you may not want the entire batch to fail due to a failed operation.

wise decision making

By using Promise.allSettled(), you can make more informed decisions after getting the results of all promises. For example, when you get data from different APIs and one of them fails, you can decide whether to continue processing the data or provide a notification with an error message.

Enhanced user experience

Often it’s better to provide the user with necessary partial results and error notifications than to fail the entire operation with some generic message. Promise.allSettled() makes this approach easy to implement.

Summarize

In summary, Promise.all() can be valuable in some situations, but Promise.allSettled() provides a more flexible and resilient approach for most scenarios.