Polyfill for Concurrent Asynchronous Operations-Promise.all

Promises in JavaScript provide a powerful way to work with asynchronous operations, allowing developers to write cleaner and more maintainable code. One of the most useful Promise methods is Promise.all, which enables concurrent execution of multiple asynchronous tasks. In this frontend interview article, we’ll explore the inner workings of Promise.all and create a polyfill to replicate its behaviour in environments where it may not be available.

Understanding Promise.all:

The Promise.all method takes an array of promises and returns a single promise that resolves when all of the input promises have been resolved or rejected as soon as one of the input promises is rejected. This makes it ideal for performing multiple asynchronous tasks in parallel and handling their results collectively.

const promise1 = new Promise((resolve, reject) => {
  resolve("With Rowdy Coders");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Crack Next");
  }, 100);
});

const promise3 = new Promise((resolve, reject) => {
  resolve("Frontend Interview");
});

const promiseArray = [promise1, promise2, promise3];

Here, Promise.all takes an array of promises as an input that returns a single promise as below.

Promise.all(promiseArray)
    .then((results)=>console.log(results))
    .catch((error)=>console.log(error))
// ["With Rowdy Coders", "Crack Next", "Frontend Interview"]

Creating the Polyfill:

To create a polyfill for Promise.all, we’ll need to replicate its behaviour by:

  1. Accepting an array of promises as input.
  2. Returning a new promise that resolves when all input promises have been resolved or rejected if any one of them rejects.
  3. Handling the asynchronous nature of promises and tracking their completion using .then and .catch

Implementation:

Promise.myAll = (arrayOfPromises) => {
  return new Promise((resolve, reject) => {
    let results = [];
    let completed = 0;
    arrayOfPromises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((result) => {
          results[index] = result;
          completed++;
          if (completed === arrayOfPromises.length) {
            resolve(results);
          }
        })
        .catch((e) => console.log(e));
    })
  });
};

Promise.myAll(promiseArray)
  .then(results => console.log(results))
  .catch(error => console.error(error));
// ["With Rowdy Coders", "Crack Next", "Frontend Interview"]

After implementing the Promise.all polyfill, it’s essential to test its functionality with various scenarios, including:

  • Arrays of promises with different lengths.
  • Promises that resolve with different types of values.
  • Promises that reject different types of errors.

By understanding how Promise.all works under the hood, we gained insight into managing concurrent asynchronous operations effectively, don’t forget to practice this on your own.

1 comment