Solution

  • Define a function which takes an array of promises as input
  • This function creates a new Promise with resolve and reject functions
  • An empty array results will store the resolved values of each promise
  • Handling empty array
  • Iterating through promises
    • For each promise, we use Promise.resolve(promises[i]) to ensure we handle non-promise values in the array.
    • For each promise, attach then and catch handlers
    • On success, store the result and check if all promises are resolved.
    • On failure, reject the main promise.
  • Return a New Promise: The function should return a new promise that handles the logic described above.

Code

This is a custom implementation of Promise.all

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let pending = promises.length;

    for (let i = 0; i < promises.length; i++) {
      Promise.resolve(promises[i]) // Handle non-promises in the array
        .then((value) => {
          results[i] = value;
          pending--;
          
          if (pending === 0) {
            resolve(results);
          }
        })
        .catch((error) => {
          reject(error);
        });
    }

    if (pending === 0) {
      // Handle empty array case
      resolve([]);
    }
  });
}

// Example usage of customPromiseAll
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, "foo"));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, "bar"));

promiseAll([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // [3, 'foo', 'bar']
  })
  .catch((error) => {
    console.error(error);
  });

Summary

  • A custom implementation of Promise.all can be created by manually iterating over the provided promises and resolving or rejecting as soon as the first one settles.
  • Ensure you have checked a non promises values.

References