简体   繁体   中英

How to treat `Promise.reject` as a first-class function?

Why can I do this:

> Promise.reject(3);
< Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

But not this:

> var f = Promise.reject;
< undefined

> f(3)
< VM2366:1 Uncaught TypeError: PromiseReject called on non-object
    at reject (<anonymous>)
    at <anonymous>:1:1

The spec defines Promise.reject as follows (emphasis mine):

25.4.4.4 Promise.reject( r )

The reject function returns a new promise rejected with the passed argument.

  1. Let C be the this value.
  2. If Type( C ) is not Object, throw a TypeError exception.
  3. Let promiseCapability be ? NewPromiseCapability( C ).
  4. Perform ? Call( promiseCapability .[[Reject]], undefined, « r »).
  5. Return promiseCapability .[[Promise]].

NOTE: The reject function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

As you can tell from this, Promise.reject expects to be called on a Promise constructor (either native promises or other compatible implementation). When treating Promise.reject as a first-class function like that, you're calling it on the global object, which is not a Promise constructor and therefore fails. 1

If you need to use Promise.reject in this way, I'd recommend to bind it first:

var f = Promise.reject.bind(Promise);
f(3); // Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

1 I'm not exactly sure why the global object is not considered an object, though, since Promise.reject.call({ }) gives Uncaught TypeError: object is not a constructor .

I believe that this is because reject is defined as a static function on the Promise object.

As such, you cannot call it as you have above, as it is called directly on the class and not on an instance of the class.

More detail about static functions and when they can and cannot be called here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

You could wrap it in a function:

function promiseReject(x) {
   return Promise.reject(x);
}

var f = promiseReject;

var out = f(3);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM