Understand Different Promise methods() in JavaScript

Understand Different Promise methods() in JavaScript

Promises are an important part of JavaScript. They are used to handle asynchronous operations which prevent the blocking of the call stack or main thread of execution.

JavaScript provides some static or built-in promise methods. But, Why do we need these methods? The answer is as simple as centering a div.

Suppose, we want to execute the promises parallelly and want the result of all promises together or we have to know which promise took less time to get resolved or which promises are rejected and fulfilled among multiple promises. How can we achieve this? There come the static methods of promises into the picture.

There are 6 different promise methods in javascript, among which Promise.all(), Promise.allSettled(), Promise.race() and Promise.any() takes an iterable (usually, an array of promises) and it returns a new promise (handled by .then() and .catch() methods ).

Let's understand these in simple steps:

1. Promise.all()

Key points to remember in Promise.all() :

  • The new promise resolves when all listed promises are resolved, and the array of their results becomes its result.
  • If any of the promises is rejected, the promise returned by Promise.all immediately rejected with that error, and other promises are ignored.

Let's understand this through code:

const p1 = new Promise((resolve, reject) => {
  resolve("resolved P1");
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "resolved P2");
});
const p3 = new Promise((resolve) => {
  resolve("resolved P3");
});
const p4 = Promise.resolve("resolved P4");

Promise.all([p1, p2, p3, p4])
  .then((values) => {
    console.log(values);
  })
  .catch((err) => {
    console.log(err);
  });

Here, all promises are getting resolved. So, in this case, Promise.all() will return a resolved promise when all input promises are resolved, and the array of their results becomes its result.

So, the output will be:

["resolved P1", "resolved P2", "resolved P3", "resolved P4"]

Now, suppose any of the above input promises, say p2, gets rejected :

const p2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "rejected P2");
});

Now, the output will be rejected P2 as we learned above, Promise.all immediately rejects with rejected promise error, and other promises are ignored.

Usecase: Suppose, we want to download several URLs in parallel and process the content once they are all done.

2. Promise.allSettled()

It's the same as Promise.all(). But, there's a major difference.

In Promise.all(), if any of the promises got rejected, the returned promise will also get rejected with that error. But, What if we want the result and value of all promises despite being resolved or rejected? In this case, Promise.allSettled() comes to battlefield.

Key points to remember in Promise.allSettled() :

  • Promise.allSettled() just waits for all promises to settle(either fulfill or reject), regardless of the result.
  • The resulting array has:

  • {status:"fulfilled", value:result} for successful responses.

  • {status:"rejected", reason:error} for errors.

Let's understand with code:

const p1 = new Promise((resolve, reject) => {
  resolve("resolved P1");
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "rejected P2");
});
const p3 = Promise.resolve("resolved P3");

Promise.allSettled([p1, p2, p3])
  .then((values) => {
    console.log(values);
  })
  .catch((err) => {
    console.log(err);
  });

OUTPUT:

[ { status:"fulfilled", value: resolved P1 },
 { status:"fulfilled", value: rejected P2 },
 { status:"fulfilled", value: resolved P3 } ]

Usecase: Suppose, we want to fetch the data about multiple users. Even if one request fails, we’re still interested in the others.

3. Promise.race()

Promise.race() is similar to the concept of running in a race and winning the race. In this, we are interested in a winner(who crosses the finishing line by hook or crook) and ignore others.

Key points to remember about Promise.race() :

  • Similar to Promise.all, but waits only for the first settled promise (either fulfilled or rejected) and gets its result (or error).
  • The promise which settles first is the winner i.e. that particular promise's result/error will be returned and all further results/errors will be ignored.

Let's understand this with code:

const p1 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, "rejected P2");
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "rejected P2");
});

Promise.race([ p1, p2 ])
  .then((value) => console.log(value))
  .catch((err) => console.log(err));

The output will be: rejected P2 because it took less time to get settled than another promise.

4. Promise.any()

This method is similar to Promise.race(), but instead of returning the first settled promise, Promise.any() returns the first promise that gets resolved or fulfilled and ignores the rest of the promises.

Key points to remember about Promise.any() :

  • It waits only for the first fulfilled promise and gets its result.
  • If all of the given promises are rejected, the returned promise is rejected with AggregateError – a special error object that stores all promise errors in its errors property.

Let's understand with code:

const p1 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, "rejected P2");
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "rejected P2");
});
const p3 = new Promise((resolve) => {
  resolve("resolved P3");
});
const p4 = Promise.resolve("resolved P4");

Promise.any([p1, p2, p3, p4])
  .then((value) => console.log(value))
  .catch((err) => console.log(err));

// OUTPUT : resolved P3

// When All PROMISES ARE REJECTED, the AGGREGATE ERROR is THROWN in PROMISE.ANY ()

Promise.any([
  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Oops!")), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Error!")), 2000))
]).catch(error => {
  console.log(error);      // AggregateError: All promises were rejected
  console.log(error.errors[0]);      // Error: Oops!
  console.log(error.errors[1]);      // Error: Error!
});

5. Promise.resolve()

Key points to remember about Promise.resolve() :

  • It creates a resolved promise with the result value.
  • async/await syntax makes Promise.resolve() somewhat obsolete.

Let's understand with code:

let p = Promise.resolve("success");

p.then((data) => console.log(data));

OUTPUT: success

6. Promise.reject()

This method is the opposite of Promise.resolve().

Key point to remember about Promise.reject() :

  • The Promise.reject() method returns a Promise object that is rejected with a given reason.

Let's understand with code:

function resolved(result) {
  console.log(result);
}
function rejected(result) {
  console.log(result);
}

Promise.reject(new Error("The promise is rejected")).then(resolved, rejected);

OUTPUT: Error: The promise is rejected

Conclusion

Congratulations! You have successfully learned different methods of Promises. Though, not every method is used more often, apart from Promise.all() method.

Here's a live link for the complete code : if-you-click-me-I-promise-I-will-open

Thank you for reading the first blog on the Different methods() of Promises! If this blog helped you understand the concept better, do leave a thumbs up and follow if you enjoyed reading.