Promise Api's Implementations

Promise Api's Implementations

Here is the Overview of some of them:

There are 6 static methods of Promise class:

  1. Promise.all(promises) – waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of Promise.all, and all other results are ignored.

  2. Promise.allSettled(promises) (recently added method) – waits for all promises to settle and returns their results as an array of objects with:

    • status: "fulfilled" or "rejected"

    • value (if fulfilled) or reason (if rejected).

  3. Promise.race(promises) – waits for the first promise to settle, and its result/error becomes the outcome.

  4. Promise.any(promises) (recently added method) – waits for the first promise to fulfill, and its result becomes the outcome. If all of the given promises are rejected, AggregateError becomes the error of Promise.any.

lets see the implementation of each :

You can find Same question in BFE.DEV list

1: implement Promise.race() :

waits for the first promise to settle, and its result/error becomes the outcome.

Understanding race(promises) in Simple Terms:

Imagine you have multiple runners (promises) competing in a race. The race function takes all of these runners as input.
Its goal is to declare a winner as soon as any runner crosses the finish line (settles, either by resolving or rejecting).
It doesn't matter who comes in first, second, or last; whoever gets there quickest determines the outcome.

function race(promises) {
  // Return a new promise
  return new Promise((resolve, reject) => {
    promises.forEach(promise => {
      // Wait for any promise to settle (resolve or reject)
      //adding .then to all the promisese to which we are iterating
      promise.then(
      function(result) { resolve(result)},
      function(error) { reject(error) }
      );
    });
  });
}

2 : Implement Promise.all() :

Waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of Promise.all, and all other results are ignored.

In bfe dev there is a clause to check if if each promise in the iterator is even a instance of promise or not, that part is taken care by solving it using the Promise.resolve() , as now weather its promise or value, you will just get the value.

function all(promises) {
  return new Promise((resolve, reject) => {
    const result = [];

    if (promises.length === 0) {
      resolve(result);
      return;
    }

    let countPending = promises.length;

    promises.forEach((promise, index) => {
      Promise.resolve(promise).then((value) => {
        result[index] = value;
        countPending--;
        if (countPending === 0)resolve(result); 
      },
      function error(error){
        reject(error);
      });
    });

  });
}

3: Implement Promise.allSettled():

  1. Promise.allSettled(promises) (recently added method) – waits for all promises to settle and returns their results as an array of objects with:

    • status: "fulfilled" or "rejected"

    • value (if fulfilled) or reason (if rejected).

Imagine it as a referee at a competition:

  • Participants: The promises represent different athletes competing in an event.

  • No Winner, Just Finish Line: Unlike promise.all, it doesn't care who finishes first; it waits for everyone to cross the finish line (settle).

  • Keeping Score: Instead of a winner, it tracks the status of each athlete: did they finish successfully ("fulfilled") or encounter an obstacle ("rejected")?

  • Final Report: Once everyone finishes, the referee announces the results for all participants, regardless of their individual performance.

function allSettled(promises) {
  if (promises.length === 0) {
    return Promise.resolve([]); // Resolve immediately if input array is empty
  }

  return new Promise((resolve, reject) => {
    let result = [];
    let settledCount = 0; // Initialize the settled count

    promises.forEach((promise, idx) => {
      Promise.resolve(promise).then(
        value => {
          result[idx] = { status: 'fulfilled', value };
        },
        reason => {
          result[idx] = { status: 'rejected', reason };
        }
      ).finally(() => {
        settledCount++; // Increment the settled count in finally rather than doing it twice in value or reason function blocks
        // Check if all promises have settled
        if (settledCount === promises.length) {
          resolve(result);
        }
      });
    });
  });
}

implement Promise.any()

waits for the first promise to fulfill, and its result becomes the outcome. If all of the given promises are rejected, AggregateErrorbecomes the error of Promise.any.

function any(promises) {
  // your code here
  if (!promises.length) throw new AggregateError("No Promise passed");

  return new Promise((resolve, reject) => {
    let settledCount = 0, let errors = [];
    promises.forEach((promise, index) => promise
      .then(data => resolve(data))
      .catch(err => {
        errors[index] = err;
        settledCount++;
        if (settledCount === promises.length) reject(new AggregateError(
          'No Promise in Promise.any was resolved',
          errors
        ))
      })
    )
  })
}