# Exploring Promise Methods and their Polyfills in JavaScript: all(), any(), allSettled() and race()

In this article, I’ve explained the Promise methods: all(), any(), race(), allSettled() along with their polyfills.

## Promise.all()

* It accepts an iterable of promises as its argument and returns a Promise
    
* If all promises resolve, then the returned promise is resolved with an array of fulfilled values. The order of the values is the same as that of the promises.
    
* If any of the promises reject, then the returned promise is rejected with the reason of the first rejected promise.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676523116147/b88dad29-d8f9-47f5-aa67-f50a9716b293.png align="center")

### Custom implementation:

```jsx
Promise.myAll = function (promises) {
  const result = [];
  let resolvedCount = 0;

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

  return new Promise((resolve, reject) => {
    promises.forEach((promise, idx) => {
      Promise.resolve(promise)
        .then((res) => {
          result[idx] = res;
          resolvedCount++;

          if (resolvedCount === promises.length) {
            resolve(result);
          }
        })
        .catch((err) => {
            reject(err)
        });
    });
  });
};
```

### Test cases:

**Test case 1:** If all the promises resolve

```jsx
const case1 = [
  new Promise((resolve) => {
    timer2 = setTimeout(resolve, 3000, "resolved");
  }),
  200,
  Promise.resolve("Hello"),
];

Promise.myAll(case1)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// [ "resolved", 200, "Hello"]
```

**Test case 2:** If any of the promises reject

```jsx
const case2 = [
  Promise.reject("rejected"),
  new Promise((resolve, reject) => {
    timer2 = setTimeout(reject, 3000, "rejectedReason");
  }),
];

Promise.myAll(case2)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// Error: rejected
```

**Test case 3:** If an empty array

```jsx
const case3 = [];

Promise.myAll(case3)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// []
```

## Promise.any()

* It accepts an iterable of promises as its argument and returns a Promise
    
* The Promise resolves when the first promise in the array resolves. It is resolved with the value of the first promise.
    
* The Promise rejects when all the promises are rejected. It is rejected with an AggregateError which includes all the rejected promises’ reasons.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676523148098/33795c6b-9d2d-493b-8f26-2b7550a1b75e.png align="center")

### Custom implementation:

```jsx
Promise.myAny = (promises) => {
  const errorsList = new Array(promises.length);
  let counter = 0;

  return new Promise((resolve, reject) => {
    promises.forEach((promise, idx) => {
      Promise.resolve(promise)
        .then((res) => resolve(res))
        .catch((err) => {
          errorsList[idx] = err;
          counter++;

          if (counter === promises.length) {
            reject(
              new AggregateError(errorsList, "All promises were rejected")
            );
          }
        });
    });
  });
};
```

### Test cases:

**Test case 1:** If any of the promises resolve

```jsx
const case1 = [
  new Promise((resolve) => {
    timer2 = setTimeout(resolve, 3000, "resolved");
  }),
  200,
  Promise.reject("Hello"),
];

Promise.myAny(case1)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// 200
```

**Test case 2:** If all of the promises reject

```jsx
const case2 = [
  Promise.reject("rejected"),
  new Promise((resolve, reject) => {
    timer2 = setTimeout(reject, 3000, "rejectedReason");
  }),
];

Promise.myAny(case2)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err.name, err.message, err.errors));

// Output:
// Error: AggregateError All promises were rejected ["rejected", "rejectedReason"]
```

## Promise.race()

* It accepts an iterable of promises as its argument and returns a Promise
    
* It returns a Promise when any of the passed promises is settled.
    
* If the first settled promise is resolved, the returned promise is resolved.
    
* If the first settled promise is rejected, the returned promise is rejected.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676523168319/9d049adc-ee8b-4c12-9d92-52e50bf9f227.png align="center")

### Polyfill:

```jsx
Promise.myRace = (promises) => {
  return new Promise((resolve, reject) => {
    promises.forEach((promise) => {
      Promise.resolve(promise).then(resolve, reject).catch(reject);
    });
  });
};
```

### Test cases:

**Test case 1:** If the first settled promise resolves

```jsx
const case1 = [
  new Promise((resolve) => {
    timer2 = setTimeout(resolve, 3000, "resolved");
  }),
  200,
  Promise.reject("Hello"),
];

Promise.myRace(case1)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// 200
```

**Test case 2:** If the first settled promise rejects

```jsx
const case2 = [
  Promise.reject("rejected"),
  new Promise((resolve) => {
    timer2 = setTimeout(resolve, 3000, "rejectedReason");
  }),
];

Promise.myRace(case2)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// Error: rejected
```

## Promise.allSettled()

* It accepts an iterable of promises as its argument and returns a Promise
    
* It returns a Promise when all of the passed promises are settled.
    
* It is resolved with an array of values that provided the status of the promise i.e. whether it is fulfilled or rejected and the value or the reason with which the promise was fulfilled or rejected respectively.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676523181286/d742f7e7-37df-4670-bd2c-b54851378fff.png align="center")

### Polyfill:

```jsx
Promise.myAllSettled = (promises) => {
  const results = new Array(promises.length);
  let counter = 0;

  return new Promise((resolve, reject) => {
    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((res) => {
          results[index] = { status: "fulfilled", value: res };
        })
        .catch((err) => {
          results[index] = { status: "rejected", reason: err };
        })
        .finally(() => {
          counter++;
          if (counter === promises.length) {
            resolve(results);
          }
        });
    });
  });
};
```

### Test cases:

**Test case:** When all promises settle

```jsx
const case1 = [
  new Promise((resolve) => {
    timer2 = setTimeout(resolve, 3000, "resolved");
  }),
  200,
  Promise.reject("Hello"),
];

Promise.myAllSettled(case1)
  .then((res) => console.log(res))
  .catch((err) => console.log("Error: ", err));

// Output:
// [
//  { status: 'fulfilled', value: 'resolved' },
//  { status: 'fulfilled', value: 200 },
//  { status: 'rejected', reason: 'Hello' }
// ]
```

## That’s all folks 👋

Hope you liked this article! If there are any improvements that can be made in the polyfills, feel free to raise an issue here 👇

%[https://github.com/siddhigate/js-polyfills] 

Let’s connect:

* [**Twitter**](https://twitter.com/SiddhiGate)
    
* [**GitHub**](https://github.com/siddhigate)
    
* [**LinkedIn**](https://www.linkedin.com/in/siddhigate/)
