Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JavaScript Promise.all have a callback that is fired when there are success AND failures [duplicate]

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)?

like image 426
Taysky Avatar asked Oct 06 '15 20:10

Taysky


People also ask

What happens to promise all if one fails?

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.

Does promise use callback?

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.

Does promise all throw error?

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.

What is difference between promise and callback in JavaScript?

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.


2 Answers

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>
like image 102
jib Avatar answered Oct 14 '22 15:10

jib


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})
    );
  }));
}
like image 20
loganfsmyth Avatar answered Oct 14 '22 15:10

loganfsmyth