3

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#description

Thenable objects that arise along the then() chain are always resolved — the onFulfilled handler never receives a thenable object, and any thenable returned by either handler are always resolved before being passed to the next handler. This is because when constructing the new promise, the resolve and reject functions passed by the executor are saved, and when the current promise settles, the respective function will be called with the fulfillment value or rejection reason. The resolving logic comes from the resolver function passed by the > Promise() constructor.

According to my understanding, promises are not always resolved but can also be rejected.

What does this documentation mean, is there a mistake?

jwa
  • 122
  • 1
  • 7
  • The `then()` will always resolve, even if a promise is rejected. To see if a promise is rejected, you can use the `catch()` before your `then()` to see why it was rejected. – Zak Jul 24 '23 at 19:58
  • And -- Think of a "rejection" *as* a "resolution" .. Even if a `then()` is rejected .. Its rejection is given to a handler, it is then "resolved", and the script moves to the following `then()` – Zak Jul 24 '23 at 20:05
  • The sentence starting "This is because..." explains how it works... – Heretic Monkey Jul 24 '23 at 20:06
  • 1
    Hi @Zak, "*The `then()` will always resolve, even if a promise is rejected.*" - what do you mean by that? The promises are the ones that are *resolved* or *rejected*, the `then()` itself only *returns* – jwa Jul 24 '23 at 20:09

2 Answers2

5

I think your confusion is regarding the use of the word "resolved". A "resolved" promise or a thenable doesn't always means that it has fulfilled.

A "resolved" promise could be settled (rejected or fulfilled) or locked-in on another promise and waits for that other promise to settle before settling itself with the same fulfilment or rejection value. This locking of one promise on to another promise is also referred to as one promise resolving to another promise.

From MDN - Promise #Description

You will also hear the term resolved used with promises — this means that the promise is settled or "locked-in" to match the eventual state of another promise, and further resolving or rejecting it has no effect. .... Colloquially, "resolved" promises are often equivalent to "fulfilled" promises, but as illustrated in "States and fates", resolved promises can be pending or rejected as well

(emphasis mine)

Yousaf
  • 27,861
  • 6
  • 44
  • 69
  • Exactly what I was *trying* to convey .. LOL .. You have a much better grammatical syntax than I do .. The term "fulfilled" is the key here. Excellent explaination. – Zak Jul 24 '23 at 20:12
  • Hi @Yousaf, of course, I forgot here the subtle difference between *resolved* and *fulfilled*. Is a `Promise` object considered a thenable object **as well**? – jwa Jul 24 '23 at 20:22
  • 1
    Promises are resolved, yes, but I don't that's what the phrase refers to in this sentence. – Bergi Jul 24 '23 at 21:03
  • 1
    @jwa Yes, promises are thanables but not every thenable is a promise. – Yousaf Jul 25 '23 at 06:04
  • @Bergi I think the main confusion OP had was regarding the word "resolved", as they incorrectly assumed that "resolved" always means "fulfilled". Regarding the quote from MDN in question, as per my understanding, "resolving a thenable" means that instead of resolving the promise with thenable as the fulfillment value, the result of the thenable object is extracted and forwarded in the promise chain. However, I agree that the quote from MDN could be improved to further clarify the author's intention. – Yousaf Jul 25 '23 at 06:11
  • Excellent @Yousaf, now I understand the difference – jwa Jul 25 '23 at 14:07
2

This is pretty confusing indeed. For one, in the promise terminology the "resolved" state does not mean the same as "fulfilled" - a resolved promise can have been resolved with a value so that it eventually rejects. However, I don't think that is what the sentence

Thenable objects that arise along the then() chain are always resolved

even refers to. "To be resolved" does not mean the state of the thenable object, which is not known in general. Promises do have states that are well-defined and the specification describes how promise objects transition between these states. Thenable objects on the other hand are not characterised by anything apart from their .then() method, which is called with two callbacks and may do anything it wants. So unless it is a promise, a thenable object does not have a state that distinguishes pending, fulfilled and rejected, and we don't talk about it "being resolved" either.

So what else does the sentence mean then? I don't know the intention of the author but I can make a guess:

  • it might mean that any thenable objects arising along the chain are used as the argument to resolve a promise. This is a bit sloppy, as it's the promise which is being resolve()d with the thenable, not the thenable object. But still, calling Promise.resolve(thenable) might be simplified to "resolving the thenable".
  • it might mean that the result is extracted. Here the verb "resolve" is not used in its JavaScript-specific meaning, but rather in the general sense - like in "solving an equation" or "resolving a domain name". Not only is a provider resolve()ing a Promise with a value, but a consumer is resolving a promise to a value. This might take multiple steps, but in the end we are getting the eventual result value (or rejection) - not as a return value from a function call, rather as a callback argument in continuation-passing style, but still. In this same sense, we can resolve a thenable object to its result value, and that resolved value is what the chained promise gets settled with.
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I have a few questions, in the second paragraph you talk about *thenable objects*, are you trying to say **only** `Promise` objects have state and *thenable objects do not*? @Bergi – jwa Jul 24 '23 at 22:21
  • 1
    @jwa Yes, that's exactly what I was saying. Maybe they have state, maybe they don't, the point is we don't know how they will behave. The thenable object might be a promise (then it'll have a promise state and follow the promise rules), but it also might be something else. It likely has some internal state, but we don't know how that looks - and we don't care, all we want is that after calling `.then(resolve, reject)` one of the callbacks gets executed. – Bergi Jul 25 '23 at 00:06
  • I thought *thenable objects* had the same "rules", states, etc as `Promise` objects. Is there any documentation that mentions the rules for *thenable objects* (*thenable objects* but not `Promise` objects)? @Bergi – jwa Jul 25 '23 at 02:40
  • 1
    No, there are no rules whatsoever. ["thenable"](https://stackoverflow.com/a/29437927/1048572) is just a description arising from the algorithm that promises use to handle objects with a `.then` method. Of course most *useful* thenables in the real world are just promises implemented by a foreign library, but ultimately [promises are required to handle *any* thenable](http://promisesaplus.com) and there's an [extensive test suite](https://github.com/promises-aplus/promises-tests) to make sure a promise implementation can deal with any weirdness a thenable may expose. – Bergi Jul 25 '23 at 03:22
  • Excellent @Bergi, now it is a little clearer to me – jwa Jul 25 '23 at 12:32
  • @jwa Glad to have helped! You might want to consider [accepting the answer](/help/someone-answers) then – Bergi Jul 25 '23 at 12:54