Promise.all() vs. Promise.allSettled() vs. for await…of
On how to handle asynchronous iterables
Writing modern JavaScript most of the time involves handling promises. More often than not, it involves handling lots of them. The options for processing promises are manifold. There are a lot of guns in the weaponry. And although you may hit a target point blank with a sniper, getting the weapon of choice right makes the job a whole lot easier.
To help you take aim properly, I will discuss three methods of handling an iterable of promises: Promise.all() , Promise.allSettled() and for await...of .
For await…of
The asynchronous For await...of is very much comparable to its synchronous brother for of : you can loop over an iterable like an Array , Map or Set . For await of distinguishes itself by the possibility to handle asynchronous codes within the loop.
So let’s assume we have an array with the ids of 5 Pokemon. Using for await…of, we can loop over the id’s one by one, and fetch the name of the associated Pokemon using the PokéApi. If an error occurs in one of the calls, we can catch and handle it, to continue with the remainder of the loop afterwards.

Promise.all()
So how would we go about fetching the Pokemon names using Promise.all() ? This function takes an iterable of promises as its input parameter. So we can .map over the ids, fetch the names, and supply the asynchronous map as input to Promise.all . When all promises are fulfilled, the function returns an array containing the result of all promises.

The main difference between “for await…of” and “Promise.all()”
So, except for the slight difference in the return value, what is the big difference between for await...of and Promise.all() . The most important difference is that Promise.all() handles its input promises concurrently, while for await...of resolves them one at the time. So, for example, using for await...of, we would be able the stop calling the pokeApi once we found Charmander, while Promise.all() would create all promises at the same time and only complete when all are resolved.
Using for await...of, you have more granular control of the promises. So if the order in which promises complete is important to you, for await...of is your preferred choice. However, the increased control isn’t free. The fact that for await...of handles promises one by one, makes it a lot slower. In fact, in case of our Pokemon fetching, almost twice as slow, as shown in the image below. So as a rule of thumb, I recommend using Promise.all() and only switch to for await...of if the concurrent handling of promises causes problems.

“Promise.all()” versus “Promise.allSettled()”
All the calls we made to the PokéApi so far were successful. But what if an error occurs fetching one of the Pokemons? Using for await of we catch the error within each iteration. So if, for example, fetching a Pokemon with id 2 failed, we can handle the error and jump into the next iteration.
In contrast, Promise.all() fails fast by default, meaning the whole promise is rejected in case a call fails. So if an error occurs while fetching the third Pokemon, execution stops and we receive an error message.

In some cases fail fast is very convenient. Assume for example, all Pokemon names are needed to perform a subsequent operation. In such a case failing fast is fine, since you do not want to waste resources on the remaining calls.
However, in other cases you want all calls to either reject or be fulfilled. For example, if the fetched Pokemons are used for a separate subsequent task, or we want to show and access error information about each call, failing fast is bothersome.
In these situations Promise.allSettled() is a more sensible choice. This function is very similar to Promise.all() , but instead of failing fast, it returns a promise that resolves after all of the given promises have either fulfilled or rejected. The result of the previous example, with an erroneous call at index === 2 , will look as follows using Promise.allSettled() . We see that four calls are fulfilled but the call with index 2 got rejected.





