Am I misunderstanding Promise.all? I have X promises in an array and i'm trying to aggregate the success/failure ratio of the array.
Here is what I think I know:
Promise.all takes an array of promises.
If all of the promises succeed then the .then
callback is ran.
If one of the promises fail then the .catch
callback is called and the argument passed in is the value of the single raised error.
There is no callback fired which is the result of all the promises if some succeed and some fail. I.e. it can't give you an array like (pseudo code) [success, fail, success, success]
- like one would expect and one can find in many JS libraries (ajax, ember, etc).
It's like the .then
is more like a .success
, not a function that always runs after all the promises are fulfilled regardless of whether some succeeded or some failed. Why doesn't have a .when
.finally
.runThisShizNoMatterWhat
?? Or am I missing something (very probable)?
all fail-fast behavior. Promise. all is rejected if any of the elements are rejected. For example, if you pass in four promises that resolve after a timeout and one promise that rejects immediately, then Promise.
A promise is a returned object where you attach callbacks, instead of passing callbacks into a function. the place where you attach the callback after a successful completion of a task is called, . then(). inside this you pass a callback through.
all throws an error. As you can see, if one of the promises fails, then all the rest of the promises fail. Then Promise. all gets rejected.
To implement asynchronous code in JavaScript we use callback functions and promises. A callback function is passed as an argument to another function whereas Promise is something that is achieved or completed in the future.
If you're fine telling errors apart from your values, then doing what you want is as simple as:
Promise.all(array.map(promise => promise.catch(error => error)))
var log = msg => div.innerHTML += "<p>" + msg + "</p>";
var a = () => Promise.resolve(1);
var b = () => Promise.reject("error");
var c = () => Promise.resolve(3);
Promise.all([a(), b(), c()].map(p => p.catch(e => e))).then(r => log(r));
<div id="div"></div>
This is related to Bluebird Promise.all - multiple promises completed aggregating success and rejections, but that's Bluebird-specific. The core of the issue is that if you want to inspect whether something succeeded or failed, then you aren't really asking for the direct result of each promise. Instead, you'd want to transform the promises before using Promise.all
. There is no helper for this ES6-standard promises, but it is trivial to implement. In most libraries, this is known as Promise.settle
. For example
var someThings = [...]; // some list of promises that may succeed or fail
settle(someThings).then(results => {
results.forEach(result => {
if (result.state === 'fullfilled'){
console.log('succeeded', result.value);
} else {
console.log('failed', result.value);
}
});
});
function settle(arr){
return Promise.all(arr.map(promise => {
return promise.then(
value => ({state: 'fullfilled', value}),
value => ({state: 'rejected', value})
);
}));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With