
JavaScript Promise.all vs. Promise.allSettled - jonluca
https://blog.jonlu.ca/posts/promises?ref=hnm18
======
rockostrich
> I was reading the MDN docs on JavaScript promises and realized that the
> difference between Promise.all and Promise.allSettled wasn’t immediately
> obvious.

Really? I haven't dealt with JavaScript in a while so I took a look at the MDN
docs and it seems pretty obvious.

> The Promise.all() method returns a single Promise that fulfills when all of
> the promises passed as an iterable have been fulfilled

and

> The Promise.allSettled() method returns a promise that resolves after all of
> the given promises have either fulfilled or rejected, with an array of
> objects that each describes the outcome of each promise.

`all` flattens all of the promises in a single promise containing an array of
their results while `allSettled` flattens the promises into a single promise
containing an array of objects that contain the resulting value as well as the
status (which is either fulfilled or rejected).

The one catch that's not immediately obvious is pointed out by the article
which is that `all` will resolve on the first rejected promise. Except that's
also in the first paragraph of the doc:

>It rejects with the reason of the first promise that rejects

~~~
eloff
I've never heard of allSettled, but the difference seems clear to me. However,
I think you would usually want the semantics of Promise.all, allSettled seems
more for niche use cases.

~~~
locallost
If you add a .catch to a promise, then it will never reject, so you get this
with .all also. I'd also never heard of .allSettled which is a pity because I
need it frequently. For instance when I have a bunch of requests that run in
parallel, and I don't really care if they all succeed, just that they are all
complete.

------
billmalarky
Nice to see Promise.race() in there. I've used it to emulate timeout logic on
I/O functionality. Useful when your JS is operating in an environment where
there's a timeout constraint you can't control and you want your JS to
gracefully handle timing out instead of the script just being killed.

Example use case is a background job running in JS via React Native. iOS
limits these jobs to 30 seconds then kills the script. Promise.race() is one
way to regain control of the thread and begin teardown prior to iOS killing
the script, if for example the other promise is hanging past 30 seconds. Keep
in mind this is not a true timeout, the other promise will continue to try to
resolve until script is terminated.

[https://github.com/billmalarky/react-native-
queue/blob/5c45b...](https://github.com/billmalarky/react-native-
queue/blob/5c45bf92a6c24275feb753cc95366e74c754a956/Models/Worker.js#L86-L125)

------
jannes
The author seems to be a bit confused about the difference between "throwing"
and "rejecting".

> Promise.allSettled can never throw

Of course not. And Promise.all neither. Promises don't throw, they reject.

async/await is syntactic sugar on top of that, which can make it look similar
to throwing, but you will never actually "throw".

~~~
k3nt0456
Author's point is that Promise.allSettled never rejects

------
darepublic
I have never heard of all settled before and remember implementing that
functionality myself some years back

------
londons_explore
allSettled is quite new (it isn't in the version of node packaged with LTS
Ubuntu).

How does one implement the same with all?

~~~
exo128
Something like this should work:

    
    
      function allSettled(promises) {
          let settled = promises.map(p => p.then(
              v => ({status: 'fulfilled', value: v}),
              r => ({status: 'rejected', reason: r})
          ));
          return Promise.all(settled);
      }
      
      let p1 = Promise.resolve('foo');
      let p2 = Promise.resolve('bar');
      let p3 = Promise.resolve('baz');
      allSettled([p1, p2, p3]).then(console.log);
      
      let p4 = Promise.reject('err1');
      let p5 = Promise.resolve('bar');
      let p6 = Promise.reject('err3');
      allSettled([p4, p5, p6]).then(console.log);

------
flak48
> I was reading the MDN docs on JavaScript promises and realized that the
> difference between Promise.all and Promise.allSettled wasn’t immediately
> obvious.

Sorry, don't agree with you there

