Custom promise.all()

Custom promise.all()

Before jumping to write our custom Promise.all(), let's understand what it does :

Let's say we want many promises to execute in parallel and wait until all of them are resolved. Here, we use Promise.all() which takes an array of promises as parameters and returns a new promise. Promise.all() resolves or rejects according to the following conditions:

Resolves when :

  1. Promises which will be fulfilled after sometime (Eg: API which fulfills after 10 sec ).
  2. Promises that have been already fulfilled (Eg: API which fulfills before passing to .all() ).
  3. Non-promise based functions, variables, etc.

Rejects when :

  1. If one of promise gets rejected, then Promise.all() immediately rejects, completely ignoring the other ones on the list.

Example

//First promise function

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));

let data1 = async () => {
  await sleep(3000);
  return "Executed after 3 sec";
};

//second promise function
const data2 = new Promise((resolve, reject) => {
  let isLogin = true;
  if (isLogin) {
    resolve("login");
  } else {
    reject("login fail");
  }
});

data2
  .then((msg) => {
    return msg;
  })
  .catch((err) => {
    return err;
  });

//simple function

const check = () => {
  return 1 + 2;
};

// executing Promise.all()

const myPromise = Promise.all([
  data1(), 
  data2, 
  undefined, 
  check()
]);

myPromise
  .then((resolve) => console.log("resolved: ", resolve))
  .catch((error) => console.log("reject: ", error));

Output :

resolved:  
(4) ["Executed after 3 sec", "login", undefined, 3]
0: "Executed after 3 sec"
1: "login"
2: undefined
3: 3

As of now, we understood how promise.all() works . so lets make our custom promise.all() now:

To write our custom promise.all() function , we have following steps :

  • Create a function called promiseAll which accepts parameter called promiseArr.
  • This function will have two variables : result (Type: Array) & counter (Type: Number).
  • result to store the result of items in promiseArr & counter to keep count of how many items are resolved so far.
  • Finally, add a promise object and return it.
  • now, iterate the given promiseArr inside new Promise() object.
  • Each item from promiseArr is passed to Promise.resolve().
  • and , .then() & .catch() chaining methods to Promise.resolve() method to handle when the items settles in each iteration.
  • When the Promise.resolve() resolves, increment counter+1 .
  • Store the resolved items in the result variable in the respective index.
  • If counter=== promiseArr.length , then resolve the promise.
  • And if even one item in promiseArr is rejected, then discard the result and reject the outer promise.

Final Code from the above steps will look like this:

//First promise function
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));

let data1 = async () => {
  await sleep(3000);
  return "Executed after 3 sec";
};

//second promise function
const data2 = new Promise((resolve, reject) => {
  let a = 2 + 1;
  if (a === 3) {
    resolve("success");
  } else {
    reject("failed");
  }
});
data2.then((msg) => msg).catch((err) => err);

function promiseAll(promiseArr) {
  let result = Array(promiseArr.length);
  let counter = 0;

  return new Promise((resolve, reject) => {
    promiseArr.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((item) => {
          counter += 1;
          result[index] = item;

          if (counter === promiseArr.length) {
            resolve(result);
            console.log(result);
          }
        })
        .catch((error) => {
          reject(error);
          console.log(error);
        });
    });
  });
}

promiseAll([data1(), data2,undefined]);

Output

(3) ["Executed after 3 sec", "success", undefined]

Hence, this is all about promise.all() and how we can make our own custom promise.all() from scratch .