How do I tell if an object is a Promise?
Whether it's an ES6 Promise or a bluebird Promise, Q Promise, etc.
How do I test to see if a given object is a Promise?
How a promise library decides
If it has a .then
function - that's the only standard promise libraries use.
The Promises/A+ specification has a notion called then
able which is basically "an object with a then
method". Promises will and should assimilate anything with a then method. All of the promise implementation you've mentioned do this.
If we look at the specification:
2.3.3.3 if
then
is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise
It also explains the rationale for this design decision:
This treatment of
then
ables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliantthen
method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
How you should decide
You shouldn't - instead call Promise.resolve(x)
(Q(x)
in Q) that will always convert any value or external then
able into a trusted promise. It is safer and easier than performing these checks yourself.
really need to be sure?
You can always run it through the test suite :D
Checking if something is promise unnecessarily complicates the code, just use Promise.resolve
Promise.resolve(valueOrPromiseItDoesntMatter).then(function(value) {
})
Disclaimer: not a good answer to updated OP, is per-library, and won't work across realms. Check for .then
instead.
This answer, based on the spec is a way to test for a promise that works only sometimes, FYI.
Promise.resolve(obj) == obj &&
BLUEBIRD.resolve(obj) == obj
When this works it's because the algorithm explicitly demands that Promise.resolve
must return the exact object passed in if and only if it is a promise created by this constructor.
Disclaimer: not a good answer to updated OP, works for native only, and not across realms. Follow accepted answer instead.
obj instanceof Promise
should do it. Note that this may only work reliably with native es6 promises.
If you're using a shim, a promise library or anything else pretending to be promise-like, then it may be more appropriate to test for a "thenable" (anything with a .then
method), as shown in other answers here.
if (typeof thing?.then === 'function') {
// probably a promise
} else {
// definitely not a promise
}