All you need to know about Promises

What is a Promise?

A promise is a Javascript object that holds the result of a future outcome. Since Javascript is synchronous and executes each line one by one so if a task takes too long to execute, for example fetching data from a remote server then this might block the web interface for the user. We don't want this to happen, so in such cases, a promise is returned.


A Promise can have three different states.

  • Pending: The initial state.
  • Fulfilled: When the task has been successfully completed
  • Rejected: When the task has failed.

A promise is said to be settled if it is either fulfilled or rejected.

How to create a promise?

let promise = new Promise(function(resolve, reject){
    // Body of the Promise
})

How to resolve or reject a Promise?

let promise = new Promise(function(resolve, reject){
    resolve("Successful")

    reject("Failed")
})

How to handle a Promise

There are three handler methods attached to a promise that can be used to consume a promise, they are:

  • .then() - The .then() is having two arguments that take callback functions, the first argument is for the result(when the promise is resolved) and the second argument is for the error(when the promise is rejected).
    promise.then(result => console.log(result), error => console.log(error))
    
    We can omit the error callback function as it is optional and it is recommended to use .catch() block for error handling.

The .then() can return a value or a new promise than can again be consumed using a new .then(). This is known as Promise chaining and helps in removing callback hell.

fetch(URL).then(res => res.json()).then(data => console.log(data))
  • .catch() - The .catch() block is used for error handling, it is recommended to use over the .then() error callback function as multiple errors can be processed using this one .catch() handler.
    fetch(URL).then(res => res.json()).then(data => console.log(data)).catch(error => console.log(error))
    
  • .finally() - The .finally() block is used to execute a block of code irrespective of whether a promise is resolved or rejected, it is always executed. An example of using a .finally() is changing a loader variable to false.
let loading = true;
loading && console.log("Loading... ");

fetch(URL).then(res => res.json()).then(data => console.log(data)).catch(error => console.log(error)).finally(()=> {
loading= false;
console.log("Promise has been settled");
})

Different Types of Promise Methods

  • Promise.all() - accepts an array of Promises and runs all of them in parallel and returns an array of the Promise results. If any one of the Promise is rejected, then all other promise results are ignored.
  • Promise.any() - accepts an array of Promises and runs all of them in parallel and returns an value. This method is similar to .all() but this returns as soon as any promise is fulfilled or all the promises are rejected(returns an AggregateError).
  • Promise.allSettled() - accepts an array of Promises and runs all of them in parallel and returns an array. This method waits until all of the promises are settled(fulfilled or rejected).
  • Promise.race() - accepts an array of Promises and runs them in parallel and returns the value/reason of the promise which is settled first.