-1

I understand that promise 3 is rejected because it resolves to an already rejected promise (promise 2), but how does promise 3 get to reject promise 4?, what is going on behind the scenes?

Promise.resolve(6) // promise 1
 .then(function(data) {
    console.log('then 1:' + data);
    return Promise.reject(new Error('ups - rejected')); // Does it "jump" to the first catch() it finds?
 }) // promise 2 - this promise is resolved with a **rejected promise**
 .then(function (data) {
    console.log('then 2:' + data);
    return data + 1; 
 }) // promise 3
.then(function (data) {
    console.log('then 3:' + data);
    return data + 1; 
 }) // promise 4 
 .catch(function(error) { // catch of promise 4?
  console.log(error);
 });

Output:

then 1:6
index.js:57 Error: ups - rejected
    at index.js:46:27
  • What sort of answer are you looking for? Like, a link to the promise spec? Or the source code that the browser uses? Or just a high level description that rejecting a promise will also reject the next promise in the chain if it doesn't catch it? – Nicholas Tower Mar 18 '23 at 20:25
  • What is the confusion here? You are creating and instantly rejecting a promise in the first `then` callback which is handled by the `catch` callback. – damonholden Mar 18 '23 at 20:25
  • hi @damonholden that's the question, how does it "jump" from the `then()` handler that rejected to the last `catch()`? –  Mar 18 '23 at 20:28
  • hi @NicholasTower, the last one "high levvel description that reject a promise will also reject..." –  Mar 18 '23 at 20:29
  • That is just simply how the `catch` logic works in javascript, when an exception is thrown (in this case a rejected promise), the first `catch` in the callstack is what handles it. If there is no `catch` mechanism, then the whole call stack fails and an Error is thrown. – damonholden Mar 18 '23 at 20:31
  • read the mdn documentation on the `Promise.prototype.catch()`method to understand how it works here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch – damonholden Mar 18 '23 at 20:36
  • hi @Mulan you are wrong, `promise 2` (the promise returned by the first `then()`) resolves to an already rejected promise. –  Mar 18 '23 at 21:28
  • the first `then()` handler returns `Promise.reject(...` @Mulan –  Mar 18 '23 at 21:30
  • Well, now I agree @Mulan, so what's going on? –  Mar 18 '23 at 22:41
  • 2
    Please don't copy [other questions](https://stackoverflow.com/q/75776655/1048572), even if they were deleted for seemingly no reason – Bergi Mar 19 '23 at 01:22
  • sorry @Bergi, I decided to copy it because I wanted a better approach. Could you give your answer now with the question better formulated, please. I would like to know your answer with details –  Mar 19 '23 at 01:38
  • I didn't catch all your comments on the question that was closed @Bergi. You would definitely get my +1 –  Mar 19 '23 at 01:40

1 Answers1

3

Promises 3 and 4 aren't exactly skipped. As in the documentation for then(), the first argument to then provides what to do when the Promise is resolved, and the second argument provides what to do when the promise is rejected.

Both the onFulfilled and onRejected handlers mention that when the parameter is absent or not a function, the parameter is treated as an identity function:

onFulfilled: "If it is not a function, it is internally replaced with an identity function ((x) => x) which simply passes the fulfillment value forward."

onRejected: "If it is not a function, it is internally replaced with a thrower function ((x) => { throw x; }) which throws the rejection reason it received."

Because promise 2 is rejected, and because the then handler that creates promise 3 doesn't have a second argument, promise 3 just takes the same resolution as promise 2. Same with promise 4, because promise 3 is rejected and the then only has a first argument.

Because promise 4's resolution matches promise 3's and promise 2's, it approximates "skipping to the next catch" (or skipping to the next two-argument then), but only because you can't see promise 3 and promise 4 reject with the same outcome as promise 2. If you were to save them to a variable and inspect them later, you would see them rejected with the message you set in the first then block.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • hi @Jeff Bowman thank you, but, where in the documentation does it say that if there is no 2nd argument in a `then()` it takes the same resolution as the previous promise? –  Mar 18 '23 at 23:30
  • I don't remember seeing that @Jeff Bowman –  Mar 18 '23 at 23:31
  • onRejected: "If it is not a function, it is internally replaced with a thrower function (`(x) => { throw x; }`) which throws the rejection reason it received." Because the parameters are optional, they are effectively undefined if you don't pass anything. I've edited quotes into the answer. – Jeff Bowman Mar 19 '23 at 05:38