Login to disable ads
Login now and become premium user

Custom Promise.all

By-Shadab Ali

Learn how to implement a custom version of Promise.all in JavaScript, including step-by-step explanations and code examples.


Introduction to Promises

A promise is an object that represents the eventual completion (or failure) of an asynchronous operation, and provides a way to register callbacks to be executed when the operation completes.

Understanding Promise.all

The Promise.all method takes an array of promises and returns a single promise that resolves when all of the promises in the array have resolved, or rejects when any promise in the array rejects.

Implementing Custom Promise.all

function customPromiseAll(promises) {
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promises)) {
      return reject(new TypeError("Argument must be an array"));
    }
 
    let resolvedCount = 0;
    const results = [];
    const promisesCount = promises.length;
 
    if (promisesCount === 0) {
      return resolve([]);
    }
 
    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((value) => {
          resolvedCount++;
          results[index] = value;
          if (resolvedCount === promisesCount) {
            resolve(results);
          }
        })
        .catch((error) => {
          reject(error);
        });
    });
  });
}
 
// Example usage
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "foo");
});
 
customPromiseAll([promise1, promise2, promise3])
  .then((values) => {
    console.log(values); // [3, 42, "foo"]
  })
  .catch((error) => {
    console.error(error);
  });

Explanation

  • Input Validation: The function checks if the input is an array. If not, it rejects with a TypeError.
  • resolvedCount: Tracks how many promises have resolved.
  • results: Stores the resolved values of the promises.
  • promisesCount: The total number of promises.
  • Edge Case for Empty Array: If the array is empty, it resolves immediately with an empty array.

Iterating Over Promises:

  • The function iterates over each promise in the input array.
promises.forEach((promise, index) => {
  //
});
  • Ensures that even non-promise values are treated as resolved promises.
Promise.resolve(promise);
  • Handles the resolution of each promise. Increments resolvedCount. Stores the resolved value in the results array at the correct index. If all promises have resolved (resolvedCount === promisesCount), it resolves the main promise with the results array.
.then((value) => {
  resolvedCount++;
  results[index] = value;
  if (resolvedCount === promisesCount) {
    resolve(results);
  }
})
  • Handles any rejection and immediately rejects the main promise with the encountered error.
.catch((error) => {
  reject(error);
});