Last updated: Mar 3, 2024
Reading timeยท3 min
To check if a value is a Promise:
then
of type function.true
, the value is a promise.function isPromise(p) { if (typeof p === 'object' && typeof p.then === 'function') { return true; } return false; } const p1 = new Promise(resolve => { resolve(10); }); console.log(isPromise(p1)); // ๐๏ธ true console.log(isPromise({})); // ๐๏ธ false
We used the logical AND (&&) operator to chain 2 conditions.
if
block is run only if both conditions evaluate to true
.All promises have a type of object
, so this is what we check for first.
const p1 = new Promise(resolve => { resolve(10); }); console.log(typeof p1); // ๐๏ธ "object"
We access the then
property on the object and check if it has a type of
function.
Promises have a .then()
and .catch()
methods.
This conditional check would fail if someone passed in a plain object with a
then
property of type function.
function isPromise(p) { if (typeof p === 'object' && typeof p.then === 'function') { return true; } return false; } console.log(isPromise({then: () => {}})); // ๐๏ธ true
We satisfied both conditions and got a false positive.
To make the solution more robust, you can add a check for the catch()
method
as well.
function isPromise(p) { if ( typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function' ) { return true; } return false; } console.log(isPromise({then: () => {}})); // ๐๏ธ false
We added a condition that checks if the object contains a catch
method as
well.
null
value.function isPromise(p) { if ( typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function' ) { return true; } return false; } // โ Error: Cannot read property 'then' of null console.log(isPromise(null));
null
has a type of object
. This is an old bug in JavaScript that has not been fixed for backward compatibility issues.console.log(typeof null); // ๐๏ธ "object"
We can add a condition that checks if the passed-in value is not null.
function isPromise(p) { if ( p !== null && typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function' ) { return true; } return false; } console.log(isPromise(null)); // ๐๏ธ false const p1 = new Promise(resolve => { resolve(10); }); console.log(isPromise(p1)); // ๐๏ธ true
Now our solution is a bit more robust. The only way to get a false positive
would be to pass an object that contains methods named then()
and catch()
,
but is not an actual promise.
Your use case might not require this over-engineered solution. You might be just
fine with checking for an object that has the then
method.
I've also written an article on how to access the value of a Promise.
As an alternative to checking if the value is a Promise, you could directly use
the Promise.resolve()
method.
const value = Promise.resolve(42); Promise.resolve(value).then(value => { console.log(value); // ๐๏ธ 42 });
The value in the example doesn't necessarily have to be a Promise.
const value = 42; Promise.resolve(value).then(value => { console.log(value); // ๐๏ธ 42 });
Either way, our code works as expected.
The Promise.resolve() method resolves the supplied value to a Promise.
If the provided value is a Promise, then the Promise is returned, otherwise, the method returns a Promise that is resolved with the supplied value.
If the value is not a Promise, we wrap it in one to be able to use the .then()
method.
If the value is a Promise, it gets returned as is and we are still able to use
the .then()
method.
You can learn more about the related topics by checking out the following tutorials: