I have a pure JavaScript Promise (built-in implementation or poly-fill):
var promise = new Promise(function (resolve, reject) { /* ... */ });
From the specification, a Promise can be one of:
- 'settled' and 'resolved'
- 'settled' and 'rejected'
- 'pending'
I have a use case where I wish to interrogate the Promise synchronously and determine:
is the Promise settled?
if so, is the Promise resolved?
I know that I can use #then()
to schedule work to be performed asynchronously after the Promise changes state. I am NOT asking how to do this.
This question is specifically about synchronous interrogation of a Promise's state. How can I achieve this?
Bluebird.js offers this: http://bluebirdjs.com/docs/api/isfulfilled.html
You can wrap your promises in this way
Caveat: This method uses undocumented Node.js internals and could be changed without warning.
In Node you can synchronously determine a promise's state using
process.binding('util').getPromiseDetails(/* promise */);
.This will return:
[0, ]
for pending,[1, /* value */]
for fulfilled, or[2, /* value */]
for rejected.Wrapping this into a helper function:
You can add a method to Promise.prototype. It looks like this:
Edited: The first solution is not working properly, like most of the answers here. It returns "pending" until the asynchronous function ".then" is invoked, which is not happen immediately. (The same is about solutions using Promise.race). My second solution solves this problem.
You can use it on any Promise. For exemple:
Second (and correct) solution:
And use it:
Notice: In this solution you doesn't have to use the "new" operator.
in node, say
process.binding('util').getPromiseDetails(promise)
It's indeed quite annoying that this basic functionality is missing. If you're using node.js then I know of two workarounds, neither of 'em very pretty. Both snippets below implement the same API:
There doesn't seem to be any way to distinguish the last two promise states using either trick.
1. Use the V8 debug API
This is the same trick that
util.inspect
uses.2. Synchronously run microtasks
This avoids the debug API, but has some frightening semantics by causing all pending microtasks and
process.nextTick
callbacks to be run synchronously. It also has the side-effect of preventing the "unhandled promise rejection" error from ever being triggered for the inspected promise.