The combinator methods take in an iterable object as an argument. They allow you to handle the combination of these promises according to the method’s definition of handling the collection. These methods are:
It is worth noting that while
Promise.race have been a part of the specification since 2015, the other two combinator methods have not been.
Promise.allSettled recently joined the gang (so, Edge and IE support does not exist). And
Promise.any is at stage 3 of the process which means it is a candidate to be added soon-ish.
- “pending” – still waiting
- “fulfilled” – promise succeeded
- “rejected” – promise failed
- “settled” – succeeded or failed
The Promise.all method
The Promise.all method runs all the promises that have been passed to it lets you know if all the promises are fulfilled or if any one of them has been rejected. If all of them are fulfilled, it returns an array with the fulfillment value of all the promises that were input to it. If any of the promises fails, it short circuits the evaluation and rejects with the rejection value of the failed promise.
The important piece about it is the last part, that is you cannot handle partial failures. If one of the promises fails, Promse.all gets rejected.
Example outputs for the method would be:
Another important piece to note that promises themselves are not cancellable by definition (unless you are using a library that has support for it). So the promises do get executed individually, irrespective of if Promise.all gets fulfilled or rejected. The short-circuiting of Promise.all does not cancel any of the promises themself.
Potential use cases for Promise.all would be when you want to aggregate the success of multiple promises into an array when they all are successful and not get the result if even one of them fails. A potential use case will be that you are making multiple API calls to different services and you want to display a component only once after all of them have succeeded. And if any of the calls fail, you want to show an error message to the user since the data set is incomplete. In that case, Promise.all makes perfect sense.
The Promise.allSettled method
Once all promises are settled, this method returns an array of objects. Each object has a status key with the value of the promise (fulfilled or rejected), and the other one will be the value if the promise is fulfilled or the reason if it got rejected.
Promise.allSettled does not get rejected if any of the promises are rejected and so the only case when it will be rejected would be when there is an error iterating over the promises. Let’s look into an example:
Promise.allSettled should become the defacto for making a lot of API calls since it does not short circuit at all and gives you all the values of all promises. It gives you a handler to perform operations when all things are done, irrespective of whether they resolved or got rejected. And it would rarely get rejected, so you do not need to worry about those catch statements as well.
The only caveat is that if one of the promises is pending, this method is not called until it gets fulfilled, which can cause error handling to be delayed for some time.
The Promise.race method
Let’s dive into the example for this one:
Promise.race can be used to create a pseudo version of a cancellable promise that times out after a certain time period.
The Promise.any method
This method is similar to the race method in the form that it only gets fulfilled when one of the input promises gets fulfilled. The only difference is that it does not care about rejections. It will only get rejected if all the input promises are rejected.
Even though the first two promises rejected before the third one, any will only resolve when it gets the first one that gets resolved, that is the third one. This can be useful if you are querying multiple endpoints and you wish to take the data from the one which returns the fastest.