javascriptlanguage-lawyerasynchronous-javascript

Passing a primitive to a then handler


This is an interesting observation that I have made when experimenting with promises in JS. Consider this code:

Promise.resolve(1).then(2).then(console.log);

This prints out 1 as its output. Why didn't the native-implemented promise API throw an exception? What is the benefit of "skipping" the non-function argument when it is being ignored anyway? I woud really apreciate an answer

This post is found in MDN.


Solution

  • The way modern promises work is defined by the ECMAScript spec. But promises already existed before they were added as a core part of the language, so for backwards compatibility they were designed to match the behavior of community-built promises. The spec that was used by the community is called Promises/A+, and the relevant part is this:

    2.2 The then method

    A promise’s then method accepts two arguments:
    promise.then(onFulfilled, onRejected)

    2.2.1 Both onFulfilled and onRejected are optional arguments:
    2.2.1.1 If onFulfilled is not a function, it must be ignored.
    2.2.1.2 If onRejected is not a function, it must be ignored.

    ECMAScript has inherited that behavior in its spec. That spec is much harder to read, but i think it's this part from PerformPromiseThen

    1. If IsCallable(onFulfilled) is false, then
      a. Let onFulfilledJobCallback be empty.

    As for why they chose to design them this way, I don't know.