Why is it possible to pass in a non-function parameter to Promise.then() without causing an error?

后端 未结 3 1189
天命终不由人
天命终不由人 2020-12-10 19:34

I have the following:

new Promise(resolve => setTimeout(resolve, 2000))
    .then(() => console.log(\"after 2 seconds\"));

new Promise(resolve => s         


        
3条回答
  •  旧时难觅i
    2020-12-10 19:56

    Why does console.log("before 2 seconds (instantly)") get executed right away (or at all)?

    A function's parameters are evaluated before the function is called. When you do alert(1+2) you expect 1+2 to be evaluated first, and when you do alert(console.log("...")) you should likewise expect console.log("...") to be evaluated first. There's nothing special about then; it's just a regular function and its arguments are treated the same as any other function's arguments.

    Why didn't the second Promise raise an exception when I didn't pass in a function?

    Because console.log returns undefined, and the language specification (ECMAScript 2015) says what should happen when you call then(undefined), and it's not throwing an exception. Let's look at what it does say:

    25.4.5.3.1 PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )

    The abstract operation PerformPromiseThen performs the “then” operation on promise using onFulfilled and onRejected as its settlement actions. The result is resultCapability’s promise.

    1. Assert: IsPromise(promise) is true.
    2. Assert: resultCapability is a PromiseCapability record.
    3. If IsCallable(onFulfilled) is false, then
      1. Let onFulfilled be "Identity".
    4. If IsCallable(onRejected) is false, then
      1. Let onRejected be "Thrower".
    5. Let fulfillReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onFulfilled }.
    6. ...

    The salient points here are (3) and (5). In (3), since onFulfilled is undefined, IsCallable(onFulfilled) is false and so onFulfilled is set to "Identity". Then, in (5), a PromiseReaction is created with the [[Handler]] onFulfulled, which we know is "Identity".

    Here's what the section PromiseReaction Records says about "Identity":

    If [[Handler]] is "Identity" it is equivalent to a function that simply returns its first argument.

    So there you have it. Calling then(undefined) is basically the same as calling then(a => a), which is why you don't get an error.

提交回复
热议问题