3

Given

var promises = [Promise.resolve("a"), Promise.reject("b")];

Promise.all(promises.map(function(p, index) {
  return p.then(function(data) {
    console.log("inside .map()", data, "index", index)
    return data
  }, function(err) {
    console.log(err);
    return err
  })
}))
.then(function(complete) {
  console.log("all promises after .map()", complete)
}, function(err) {
  console.log("err", err)
})

why is onRejected not called at .then(onFulfilled, onRejected) following Promise.all() ?

jsfiddle https://jsfiddle.net/9gprLc7q/

https://jsfiddle.net/9gprLc7q/

guest271314
  • 1
  • 15
  • 104
  • 177
  • because you don't handle the error in the mapping, what you return is still resolved promise. if you do `Promise.reject(err)` it will work properly. – Yerken Jan 27 '16 at 16:03
  • 1
    Closely related if not even duplicate (but not an obvious one): [Chained promises not passing on rejection](http://stackoverflow.com/q/16371129/1048572). You `return err` instead of re`throw`ing it. – Bergi Jan 27 '16 at 16:17

2 Answers2

3

You need to understand that handling a rejection results in putting the promise back on the success path. One approach to this is to re-throw in the failure handler, like this:

var promises = [Promise.resolve("a"), Promise.reject("b")];

Promise.all(promises.map(function(p, index) {
  return p.then(function(data) {
    console.log("inside .map()", data, "index", index)
    return data
  }, function(err) {
    console.log(err);

    // RE-THROW!!
    throw err;                  

  })
}))
.then(...

If the purpose of the rejection handler is merely to log, then you could move it out of the chain:

Promise.all(promises.map(function(p, index) {

  // MOVE ERROR HANDLER OUTSIDE OF CHAIN
  p.catch(function(e) { console.log(e); });

  return p.then(function(data) {
    console.log("inside .map()", data, "index", index)
    return data
  })
}))
.then(...
1

What you've really done here is something like this:

https://jsfiddle.net/9gprLc7q/5/

var notRejectedPromise = 
    Promise.reject("b")
      .then((resolved) => resolved, (err) => err)

var promises = [Promise.resolve("a"), notRejectedPromise];

Promise.all(promises)
.then(function(complete) {
  console.log("all promises after .map()", complete)
}, function(err) {
  console.log("err", err)
})

But deciding to handle the err portion by returning whatever err was, you returned a string. This is not a reason for rejection.

To actually cause the Promise.all() to reject you need an error to occur in either the resolved or rejected portion of .then

Given this, if you return a rejected promise, it will reject:

https://jsfiddle.net/9gprLc7q/3/

console.log(err)

to

return Promise.reject(err)

Alternatively you can throw an error: https://jsfiddle.net/9gprLc7q/2/

console.log(err)

to

throw new Error(err)
m0meni
  • 16,006
  • 16
  • 82
  • 141
  • Why does removing `.then()` at `.map()` return expected results https://jsfiddle.net/9gprLc7q/4/ ? Why is rejected `Promise` converted to resolved `Promise` ? – guest271314 Jan 27 '16 at 16:14
  • @guest271314 this is because you never attached a `.then` to the rejected promise. So now instead of returning `"b"`, which isn't a reject, it returns itself `Promise.reject("b")` which is a rejected value. – m0meni Jan 27 '16 at 16:15
  • @guest271314 maybe this will help https://jsfiddle.net/9gprLc7q/5/. The err portion returns a string instead of a `Promise.reject` when you do `return err` in your original code – m0meni Jan 27 '16 at 16:20
  • Returned expected results using only `throw err` https://jsfiddle.net/9gprLc7q/6/ , without `new Error(err)` – guest271314 Jan 27 '16 at 16:24
  • @guest271314 Yeah that's another topic to talk about haha. From what I've read `throw new Error(err)` is a better alternative to `throw err`, but they both basically do the same thing. Do you understand now? – m0meni Jan 27 '16 at 16:25
  • _"From what I've read throw new Error(err) is a better alternative to throw err"_ Appears on-topic from vantage, here. Links to discussion have read on this topic ? _"Do you understand now?"_ Yes – guest271314 Jan 27 '16 at 16:27
  • 1
    @guest271314 here you go http://stackoverflow.com/questions/9156176/javascript-what-is-the-difference-in-throw-new-error-and-throwobject :D – m0meni Jan 27 '16 at 16:28