-1

I can't really understand how the promise will work here:

Promise.resolve(1)
    .then(x => x + 1)
    .then(x => { throw x })
    .then(x => console.log(x))
    .catch(err => console.log(err)) // 2
    .then(x => Promise.resolve(1))
    .catch(err => console.log(err))
    .then(x => console.log(x)) // 1

from MDN: The Promise returned by catch() is rejected if onRejected throws an error or returns a Promise which is itself rejected; otherwise, it is resolved. , so why it doesn't stop after catch?

Aygul
  • 3
  • 2

1 Answers1

0

Here's what's going on:

  1. Promise.resolve(1) creates a promise fulfilled with the value 1.
  2. .then(x => x + 1) adds a fulfillment handler to that promise, creating a new promise (.then, .catch, and .finally always create promise). When the fulfillment handler is called, it will take the fulfillment value of the promise it was called on as x, add 1 to it, and use that to fulfill its promise.
  3. .then(x => { throw x }) adds a fulfillment handler to the promise from Step 2, creating a new promise. When called, the fulfillment handler will take the fulfillment value of the promise it was attached to (1 + 1 is 2) and use that to throw a value. This rejects the promise this second .then created.
  4. .catch(err => console.log(err)) adds a rejection handler to that promise. When the rejection handler is called, it takes the rejection reasons (which we know will be 2) as err and logs it. Since the rejection handler doesn't throw an error or return a promise that is rejected or will reject, it converts rejection to fulfillment. In this case, it uses the return value of console.log to fulfill its promise. That value is undefined.

...and then the same sort of pattern is repeated again.

Key bits there are:

  • .then, .catch, and .finally create promises
  • If you return a value (explicitly or implicitly) from a fulfillment or rejection handler, and that value isn't a promise that is rejected or will reject, it fulfills the promise .then or .catch created with that value.
  • If you throw (or return a promise that is rejected or will reject) in a .then or .catch handler, you reject the promise .then or .catch created.

If you're not entirely clear on the terminology around promises ("fulfill," "reject," "resolve" [which I didn't use above, but the code did]), I have a blog post for that. ;-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • FWIW, I go into promises in detail in Chapter 8 of my recent book *JavaScript: The New Toys*. Links in my profile if you're interested. – T.J. Crowder Apr 03 '21 at 11:54
  • [The Promise returned by catch() is rejected if onRejected throws an error or returns a Promise which is itself rejected; otherwise, it is resolved.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch), so why it doesn't stop after catch? – Aygul Apr 03 '21 at 12:41
  • @Aygul - See #4 above. The `catch` handler doesn't throw an error or return a promise that is rejected (or will reject), so it converts rejection into fulfillment (like a `catch` on a `try`/`catch` does if you don't `throw` from it). – T.J. Crowder Apr 03 '21 at 12:48
  • @Aygul You wrote it yourself: "*otherwise, it is resolved*". Why would you expect it to "stop"? Do you mean it should never settle to anything? – Bergi Apr 03 '21 at 15:57