Promise
Published: 2022-06-09 21:37:49

> The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

Promise has 3 states:

- pending

- fulfilled

- rejected

A pending promise can either be fulfilled with a value or rejected with a reason (error). When fulfilled happens, then() method is called to handle operation and if rejected happens, catch() method is called to handle operations.

![alt text](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/promises.png)

**Constructor**
The Promise constructor is primarily used to wrap functions that do not already support promises.

```
const promise = new Promise((resolve, reject) => {
  // your asynchronous task
  // resolve or reject
});
```

resolve and reject are also functions/ Their signatures are simple: they accept a single parameter of any type.

```
  resolve(value) // call on resolved
  reject (reason) // call on rejected
```
The resolve value parameter can be another promise object, in which case the promise gets dynamically inserted into the promise chain.
At the time when the constructor generates the new Promise object, it also generates a corresponding pair of functions for resolve and reject; these are "tethered" to the Promise object.

When called via new, the Promise constructor returns a promise object. The promise object will become "resolved" when either of the functions resolve or reject are invoked. Note that if you call resolve or reject and pass another Promise object as an argument, you can say that it is "resolved", but still cannot be said to be "settled".

Lets see a function that takes a URL and then returns a new promise

```
function myAsyncFunction(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open("GET", url)
    xhr.onload = () => resolve(xhr.responseText)
    xhr.onerror = () => reject(xhr.statusText)
    xhr.send()
  });
}
```

**Consuming a promise**
1. then() method - it accepts two callback functions: onFulfilled and onRejected.
`promise.then(onFulfilled,onRejected);`

2. catch() method - If you want to get the error only when the state of the promise is rejected, you can use this
`promise.catch(onRejected);`

3. finally() method - It lets you execute the same piece of code whether the promise is fulfilled or rejected.

Example Shown below

```

const render = () => {
  //...
};

getUsers()
  .then((users) => {
    console.log(users);
  })
  .catch((error) => {
    console.log(error);
  })
  .finally(() => {
    render();
  });

```

**Promises chaining**
then() method generates a new promise which can optionally be used for chaining
Example
```
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('foo');
  }, 300);
});

myPromise
  .then(handleResolvedA, handleRejectedA)
  .then(handleResolvedB, handleRejectedB)
  .then(handleResolvedC, handleRejectedC);

```
**Static Methods**

**- Promise.all(iterable)**
   It takes an iterable of promises as input and returns a single Promise that resolves to an array of the results of the input promises.
   It resolves after all are resolved or fails as soon as any fails.
Example -

```
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
```

**- Promise.allSettled(iterable)**
   It takes an iterable of promises as input and returns a single Promise that resolves to an array of the results of the input promises.
   It resolves after all are settled (i.e. either resolved or rejected).
Example -

```
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

**- Promise.allSettled(promises).**
  then((results) => results.forEach((result) => console.log(result.status)));
```

**- Promise.any(iterable)**
   As soon as any promise resolves, it returns the value of that promise
Example -

```
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));

const promises = [promise1, promise2, promise3];

Promise.any(promises).then((value) => console.log(value));
```

**- Promise.race(iterable)**
   Wait until any of the promises is fulfilled or rejected.
If the returned promise resolves, it is resolved with the value of the first promise in the iterable that resolved.
If it rejects, it is rejected with the reason from the first promise that was rejected.
Example -

```
const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // Both resolve, but promise2 is faster
});
```

**- Promise.reject(reason)**
   Returns a new Promise object that is rejected with the given reason.

**- Promise.resolve(value)**
   Returns a new Promise object that is resolved with the given value.

**Conclusion**

A promise is an object that encapsulates the result of an asynchronous operation.

A promise starts in the pending state and ends in either fulfilled state or rejected state.

Use then() method to schedule a callback to be executed when the promise is fulfilled, and catch() method to schedule a callback to be invoked when the promise is rejected.

Place the code that you want to execute in the finally() method whether the promise is fulfilled or rejected.