2

This article goes over the individual promise combinators:

Promise.all

Promise.any

Promise.race

Promise.allSettled

But what I don't see is, a way to run all promises, but not short circuit when an individual promise rejects. How do I ensure all promises are run, but I can handle a rejection and the resolution of all of them?

citizen conn
  • 15,300
  • 3
  • 58
  • 80
  • 1
    Didn't you actually describe `allSettled` proposal? – Andrey Jun 19 '19 at 13:47
  • Promises run when you create them. "A way to run all promises" -- just create all the promises and they will run, that's it. Also a promise can either reject or resolve, not both -- "handle rejection and the resolution of all of them" seems to contradict my statement. Can you rephrase your question with this in mind? – Armen Michaeli Jun 19 '19 at 13:50
  • Multiple ways of solving it here: [ES6 Promise.all() error handle - Is .settle() needed?](https://stackoverflow.com/questions/36605253/es6-promise-all-error-handle-is-settle-needed/36605453#36605453) or [Why does JavaScript's `Promise.all` not run all promises in failure conditions?](https://stackoverflow.com/questions/42304394/why-does-javascripts-promise-all-not-run-all-promises-in-failure-conditions/42304596#42304596). – jfriend00 Jun 19 '19 at 17:26

1 Answers1

4

You can add a catch to the individual promises that indicates how you want the errors to appear in the final result. Because catch returns a promise, when you run Promise.all you will be able to get the errors as results. For example:

// some promises:
let p = [
    Promise.resolve("val1"),
    Promise.reject("some error"),
    Promise.resolve("val3")
  ]
  
 let results = Promise.all(p.map(pr => 
       pr
       .then(v=> "value: " + v)
       .catch(e => "error: " + e)))  // add catch to prevent errors from stopping all()
  
 results.then(console.log)
Mark
  • 90,562
  • 7
  • 108
  • 148
  • `catch` is not required nor is it actually the same thing as providing a second argument to the preceding `then` call. `catch` deals with the rejected value of a promise, but it's a promise created with the value returned by reject handler of the previous promise, i.e. a second promise is being created and handled. In short, given a promise `A`, `A.then(on_success).catch(on_failure)` is *not* the same thing as `A.then(on_success, on_failure)`. – Armen Michaeli Jun 19 '19 at 13:53
  • I'm not sure where I said these two things were identical @amn. But on the subject, please see: [When is .then(success, fail) considered an antipattern for promises?](https://stackoverflow.com/questions/24662289/when-is-thensuccess-fail-considered-an-antipattern-for-promises) – Mark Jun 19 '19 at 14:00
  • Rest assured, in your snippet, using `catch` is unnecessary and not doing so wouldn't be a case of an anti-pattern. `Promise.all(p.map(pr => pr.then(value => ({value}), reason => ({reason}))))` yields a promise that resolves with an array of promises, where each such promise resolves with either an object with a `value` property referring to the resolved value of the original encapsulated promise, or an object with a `reason` property referring to the rejection reason of that original encapsulated promise. Similar to your example, but without one `then` _and_ one `catch`. – Armen Michaeli Jun 19 '19 at 15:10