Skip to content

Promises

Promises are used to handle asynchronous operations. Provide an alternative approach for callbacks by reducing the callback hell and writing cleaner code.

  1. Pending. Initial state of the promise before an operation begins.
  2. Fufilled. Indicates the specified operation was completed.
  3. Rejected. Indicate operation did not complete, error value will be thrown.

A promise must follow a specific set of rules,

Section titled “A promise must follow a specific set of rules,”
  1. A promise is an object that supplies a standard-compliant .then() method
  2. A pending promise may transition into either fufilled or rejected state
  3. A fufilled or rejected promise is settled must not transition into any other state.
  4. Once a promise is settled, value must not change.

promise.all

  • Takes an array of promises as as input (iterable) and gets resolved when all the promises get resolved or one of them gets rejected.
Promise.all([Promise1, Promise2, Promise3])
.then(result) => { console.log(result) })
.catch(error => console.log(`Error in promises ${error}`))

promise.race

var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value); // "two" // Both promises will resolve, but promise2 is faster
});

Promise.all() is a powerful JavaScript method that allows you to handle multiple asynchronous operations concurrently. It takes an iterable of promises and returns a single promise that fulfills when all of the input promises fulfill, or rejects if any of the input promises reject.

Here’s a breakdown of when Promise.all() is a good choice:

  • Independent Asynchronous Tasks: Use Promise.all() when you have multiple asynchronous tasks that do not depend on each other and can be executed simultaneously. For example, fetching data from multiple independent API endpoints. javascripttutorial.net
  • Aggregating Results: When you need to collect the results from all promises before proceeding. Promise.all() resolves with an array containing the fulfillment values of all the input promises, in the same order as the promises were provided. developer.mozilla.org
  • “Fail-Fast” Behavior is Desired: Promise.all() rejects immediately if any of the input promises reject. This “fail-fast” behavior is useful when the entire operation is considered a failure if even one part fails. logrocket.com
  • Concurrent Operations for Performance: When you want to speed up execution by running multiple asynchronous operations at the same time, rather than sequentially. developer.mozilla.org
  • Running Multiple API Requests: A common use case is to make several API calls simultaneously and process their responses together. educative.io
  • Concurrent File Reading (e.g., in Node.js): When reading multiple files in parallel to improve efficiency before processing their content. educative.io
const promise1 = Promise.resolve(3);
const promise2 = 42; // Non-promise values are treated as already resolved promises
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // Expected output: [3, 42, "foo"]
});

While Promise.all() is very useful, there are situations where alternative methods might be more appropriate:

  • When Not All Promises Need to Succeed: If you want to get results from all promises, even if some fail, use Promise.allSettled(). logrocket.com

  • When You Only Need the First Success: If you only care about the result of the first promise that fulfills, use Promise.any(). logrocket.com

  • When You Need the First Settled Result (Success or Failure): If you need the result of the first promise that settles (either resolves or rejects), use Promise.race(). logrocket.com

  • Variable Response Times Leading to Inefficiency: If requests have highly variable response times, Promise.all() might not be the most efficient if one slow request holds up the whole process. Consider sequential processing or rate limiting in such cases. medium.com

  • High Memory Consumption with Large Data: If promises return very large data, Promise.all() could lead to high memory usage as all results are stored. Consider processing data in chunks or using streaming. medium.com

In summary, Promise.all() is ideal for scenarios where you need to run multiple asynchronous tasks concurrently and require all of them to succeed for the overall operation to be considered successful.