DEV Community

Cover image for What's wrong with Promise.allSettled() and Promise.any()❓

What's wrong with Promise.allSettled() and Promise.any()❓

Vitaliy Potapov on July 17, 2019

I've recently read the Promise combinators article in v8 blog. It's about two upcoming methods in Promise API: Promise.allSettled() and Promise.any...
Collapse
 
ressom profile image
Jason Mosser

allSettled is useful in at least two principle cases. First, when calling multiple operations that are recoverable on failure. Second, calling multiple operations where 'silent' behavior is desired.

It avoids using errors for flow control, which is good.

const [r1, r2] = await Promise.allSettled([op1(), op2()]);

// decode state of the operations and retry if needed //
// or, if one does not care about the results, just invoke it and move on //
Collapse
 
vitalets profile image
Vitaliy Potapov • Edited

I totally agree - this is useful scenario.
My point is that it can be easily achieved with current api without introducing new methods:

const [r1, r2] = await Promise.all([op1(), op2()].map(p => p.catch(e => e)));

// decode state of operations by simply checking "instanceof Error".
Collapse
 
itscodingthing profile image
Bhanu Pratap Singh

I think it is more about the complexity or how much code you write to achieve same functionality without worrying about the other things.

Collapse
 
zakalwe314 profile image
Euan Smith

I use Promise.any A LOT. I'm using it again on a project right now. I was overjoyed to see it proposed to become part of the spec. Frankly, it is what Promice.race should have been in the first place. So, let me ask you a question back - while you might not need Promise.any for you code, have you every used Promise.race?

I would also disagree with your assertion that it is different in nature from other in-build Promise calls. It is actually the dual of Promise.all. Promise.any will return with the FIRST SUCCESS or ALL FAILURES. Promise.all will return the FIRST FAILURE or ALL SUCCESSES (which points to a quick and dirty way of implementing it, although I wouldn't really recommend it).

It is true that the aggregate error feels a bit clunky to say the least, however I can't see an alternative and I'm certainly willing to put up with it.

Collapse
 
kimamula profile image
Kenji Imamula • Edited

I use Promise.race for implementing timeout. See, for example, here to see how Promise.race can be used to implement timeout.

Currently I am looking for good real world examples of the use case of Promise.any and I would appreciate if you could share your use case.

Collapse
 
zakalwe314 profile image
Euan Smith • Edited

My typical use case is that I have a number of possible locations of a given resource. There may be multiple servers for the same thing (e.g. primary and backup, or different geographical locations). Some of these might fail, but you don't care so long as you can find one which succeeds. In this case Promise.any is the right pattern as it only rejects if ALL of the endpoints reject.

A second use case is that I have multiple routes to the same server. One might be a route via the internet and one might be locally over a LAN - both or neither of these routes might be available. Again Promise.any is the right pattern.

If what you do is work with cloud services then it is possible you will never need this - you don't have availability or routing complications. However I work with distributed services and IoT devices (we develop the hardware and the software) sometimes operating in networks with poor or otherwise limited connectivity. In this case Promise.any is an essential tool in establishing a connection.

Thread Thread
 
kimamula profile image
Kenji Imamula

Thanks for sharing! That makes sense.

Collapse
 
yegorzaremba profile image
Yegor <3

we will use Promise.any here github.com/nsfw-filter/nsfw-filter...

Collapse
 
larsivi profile image
Lars Ivar Igesund

Late to the party I guess, but there are also some other gotchas in Promise.allSettled.

You show the example with 3 fetch calls in an array, which you so pass to allSettled. Depending on what else is going on, maybe the logic to build the promise array is a bit convoluted and maybe a bit slow. If you want to handle any errors coming out of those promises, you will in fact have missed them if the promises settled prior to getting into allSettled.

I also find it rather annoying that you can't return a value with the rejected promises. If you're going to handle the rejections, you would really like more information, in a structured manner, rather than just get access to an error string/reason.

Collapse
 
tblabs profile image
Tomasz Budrewicz

+1

Collapse
 
al_p_664cee7c7a4c4393f08b profile image
Al P

Hi Brother. Do you have the same sample repo project for PlayWright with BDD frame work java. Do you have a mail id to reach out?

Collapse
 
vitalets profile image
Vitaliy Potapov

Hey! For Java no, only for JavaScript github.com/vitalets/playwright-bdd...