Lets say I have a set of promises that are making network requests, of which one will fail:
// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]
Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) // This is executed
Lets say I want to wait until all of these have finished, regardless of if one has failed. There might be a network error for a resource that I can live without, but which if I can get, I want before I proceed. I want to handle network failures gracefully.
Since Promises.all
doesn't leave any room for this, what is the recommended pattern for handling this, without using a promises library?
The
Promise.all
will swallow any rejected promise and store the error in a variable, so it will return when all of the promises have resolved. Then you can re-throw the error out, or do whatever. In this way, I guess you would get out the last rejection instead of the first one.I've been using following codes since ES5.
The usage signature is just like
Promise.all
. The major difference is thatPromise.wait
will wait for all the promises to finish their jobs.Similar answer, but more idiomatic for ES6 perhaps:
Depending on the type(s) of values returned, errors can often be distinguished easily enough (e.g. use
undefined
for "don't care",typeof
for plain non-object values,result.message
,result.toString().startsWith("Error:")
etc.)You can execute your logic sequentially via synchronous executor nsynjs. It will pause on each promise, wait for resolution/rejection, and either assign resolve's result to
data
property, or throw an exception (for handling that you will need try/catch block). Here is an example:Here's my custom
settledPromiseAll()
Compared to
Promise.all
If all promises are resolved, it performs exactly as the standard one.
If one of more promises are rejected, it returns the first one rejected much the same as the standard one but unlike it waits for all promises to resolve/reject.
For the brave we could change
Promise.all()
:CAREFUL. In general we never change built-ins, as it might break other unrelated JS libraries or clash with future changes to JS standards.
My
settledPromiseall
is backward compatible withPromise.all
and extends its functionality.People who are developing standards -- why not include this to a new Promise standard?
I would do: