Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
1.1.
Promise
2.
Promise Chaining
2.1.
Multiple handlers for a promise
3.
Promise.all()
3.1.
Syntax:
3.2.
Example: 
4.
Frequently Asked Questions
4.1.
What is a Promise?
4.2.
What is Promise Chaining?
4.3.
What is promise.all()?
4.4.
Difference between promise.all() and promise.allSetteled()?
4.5.
Are multiple handlers for a promise the same as promise chaining?
5.
Conclusion
Last Updated: Mar 27, 2024

Promise Chaining and promise.all

Introduction

This article will look at how to use the JavaScript promise chaining technique to execute asynchronous processes in a logical order. We will also understand promise.all() method.

Also Read, Javascript hasOwnProperty

Promise

A promise represents an asynchronous operation's future result. Promises are frequently utilized to handle asynchronous processes in JavaScript. The promise allows asynchronous methods to return values the same way that synchronous methods do. Instead of delivering the final value right away, the asynchronous method returns a promise to supply the value in the future.

A Promise is usually in one of the three states:

  1. Pending: If a promise is neither fulfilled nor rejected, it is said to be pending. It is the initial state.
  2. Fulfilled: It means that the operation is complete. If it is fulfilled promise.then(f) will call f as quickly as possible.
  3. Rejected: It means that the operation failed.

We use the new keyword to construct a promise, and we supply a function to the Promise object. An executor is a function that takes two arguments: resolve for success and reject for failure:

const p = new Promise((resolve, reject) => { 
  ... 
});

Promise Chaining

One of the things that makes a promise so great and easy to implement is promise chaining. We can run a series of asynchronous jobs in a chain, with each task starting as soon as the preceding one finishes.

Sometimes we want to run two or more asynchronous operations in a row, with the next operation starting with the output of the last one. Consider the following scenario:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100); //(*)
});

p.then((result) => { //(**)
    console.log(result); //10
    return result * 2;
}).then((result) => { //(***)
    console.log(result); //20
    return result * 3;
}).then((result) => { //(****)
    console.log(result); //60
    return result * 4;
});

Output:

10
20
60

The concept is to send the outcome through a chain of .then handlers.

Here's how it goes:

  1. The initial promise resolves in 3 seconds (*), after which the.then handler (**) is executed, which produces a new promise (resolved with value 20).
  2. The following handler (***) receives the previous handler's result, processes it (doubles), and passes it on to the next handler.
  3. And so on.
  4. We can see the succession of alert calls can, as a result, be transmitted through the chain of handlers: 10→ 20→ 60

The return value from the first then() method is provided to the second then() method, and you can keep calling the then() method over and over again; this mechanism of calling then() methods like this is known as a promise chain.

Multiple handlers for a promise

It's not promise chaining if you call the then() method on a promise several times. We can technically add as many .then as we like to a single promise. This isn't the same as chaining. Consider the following scenario:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100); //(*)
});

p.then((result) => { //(**)
    console.log(result); //10
    return result * 2;
})
p.then((result) => { //(***)
    console.log(result); //10
    return result * 3;
});
p.then((result) => { //(****)
    console.log(result); //10
    return result * 4;
});

Output:

10
10
10

So the output of the above code shows the same result: 10.

We used multiple handlers to fulfil a single promise. They don't share the result; instead, they process it separately. In practice, numerous handlers for a single promise are rare. Generally, we use chaining.

A promise with several handlers:

Promise.all()

Promise.all() is nothing more than a promise that takes an array of promises as input. It resolves when all of the promises are fulfilled or rejected when one of the promises is rejected. Promise.all() method can combine the outcomes of several promises. It's often used when the overall code relies on numerous related asynchronous processes to perform correctly, all of which we want to complete before the code execution continues.

You've gathered many promises, and you'd like to do all of these asynchronous activities at once rather than using a peculiar mechanism like a loop. How are you going to do it?

There are two options available to you:

  1. You can execute all of the promises one by one or chain them together and analyze the data as it becomes available.
  2. You can execute all promises by sending an array of them to promise.all, and the method will give you a result.

Latter is preferred over the former in this case. 

Syntax:

Promise.all(iterable); // iterable: An iterable object such as an Array.

Example: 

const promise1 = Promise.resolve(25);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout( resolve, 100, 'food' );
});
Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [25, 42, "food"]

Promise. all() is a function that waits for all fulfillments (or the first rejection). Non-promise values in the iterable will be disregarded, but they will still be counted in the returned array value of the promises (if the promise is fulfilled):

// it gets fulfilled because this will be counted as if the iterable passed is empty
const p = Promise.all([1 , 2 , 3]);
// it gets fullfiled because this will be counted as if the iterable passed contains only the resolved promise with value "444"
const p2 = Promise.all([1,2,3, Promise.resolve(444)]);
// it gets fulfilled because this will be counted as if the iterable passed contains only the rejected promise with value "555"
const p3 = Promise.all([1,2,3, Promise.reject(555)]);
// using setTimeout we can execute code after the stack is empty
setTimeout(function() {
    console.log(p);
    console.log(p2);
    console.log(p3);
});

// logs
// Promise { <state>: "fulfilled", <value>: Array[3] }
// Promise { <state>: "fulfilled", <value>: Array[4] }
// Promise { <state>: "rejected", <reason>: 555 }

For better understanding practice it on an online javascript compiler.

Frequently Asked Questions

What is a Promise?

In JavaScript, promises are frequently used to handle asynchronous processes. This allows asynchronous methods to return values the same way that synchronous methods do. Instead of delivering the final value right away, the asynchronous method returns a promise to supply the value at some point in the future.

What is Promise Chaining?

A common necessity is to run two or more asynchronous operations in succession, with each following action beginning when the previous one succeeds and using the outcome of the last step. We achieve this by promise chaining.

What is promise.all()?

Promise.all() is nothing more than a promise that takes an array of promises as input. It resolves when all promises are fulfilled or get rejected when one of them is rejected. This method can be used to combine the outcomes of several promises.

Difference between promise.all() and promise.allSetteled()?

If we have many promises that we want to perform, the promise.all() might not be the best solution if we want to return all the values, regardless if there is an error in your promises. You can do this with the promise.allSettled() method. After all of the promises have been fulfilled or refused, this procedure will return a single promise that will be resolved.

Are multiple handlers for a promise the same as promise chaining?

No, It's not promise-chaining if you call the then() method on a promise several times. We can technically add as many .then() as we like to a single promise. This isn't the same as chaining.

Conclusion

In this article, we have extensively discussed the Promise Chaining and Promise.all() method. We have discussed how to achieve promise chaining with and without the use of promise.all().

After learning about Promises, Promise chaining, and Promise.all(), are you curious to explore more articles on the topic related to JavaScript? We have you covered. Check out Basic of JavaScript, and you can also enhance your JavaScript skills with Learn and Practice JavaScript.

Refer to guided paths on Coding Ninjas Studio to upskill yourself in Data Structure and AlgorithmsCompetitive ProgrammingJavaScriptSystem Design, and many more. If you want to test your competency in coding, you may check out the mock test series and participate in contests hosted by Coding Ninjas Studio! But suppose you have just started the learning process and looking for questions asked by tech giants like Amazon, Microsoft, Uber, etc. In that case, you must look at the problemsinterview experiences, and interview bundle for placement preparations.

Nevertheless, you may consider our paid courses to give your career an edge over others!

Do upvote our blogs if you find them helpful and engaging!

Happy learning!

Live masterclass