To check if a function returns a Promise
in JavaScript, call the function (impossible without doing so), and use the instanceof
operator to check if the return value is a Promise
object.
For example:
console.log(returnsPromise(func1));
console.log(returnsPromise(func2));
console.log(returnsPromise(func3));
function returnsPromise(func) {
return func() instanceof Promise;
}
function func1() {
return new Promise((resolve) => {
resolve('Coding Beauty');
});
}
async function func2() {
return 100;
}
function func3() {
return 'Coding Beauty';
}
Unfortunately, there’s no way to check if a function returns a Promise
without invoking it and getting its result.
After getting the return value, we use instanceof
to check if it’s a Promise
instance.
Ensure Promise
return value from function
If you’re checking the function’s return value to convert a possible non-Promise
value to a Promise
, you can simply wrap the function call in the Promise.resolve()
method.
If the function’s return value is a Promise
, Promise.resolve()
will return that Promise
object.
If the function’s return value is not a Promise
, Promise.resolve()
will return a Promise
that will resolve that return value directly.
Promise.resolve(func1()).then((value) => {
console.log(value); // Coding Beauty
});
Promise.resolve(func2()).then((value) => {
console.log(value); // JavaScript;
});
// does return Promise
function func1() {
return new Promise((resolve) => {
resolve('Coding Beauty');
});
}
// does NOT return Promise
function func2() {
return 'JavaScript';
}
Check if function is async
It’s also possible to check if a function is async
, by checking if the constructor.name
property of the function is 'AsyncFunction'
:
console.log(isAsync(func1)); // false
console.log(isAsync(func2)); // true
console.log(isAsync(func3)); // false
function isAsync(func) {
return func.constructor.name === 'AsyncFunction';
}
// NOT async, but returns Promise
function func1() {
return new Promise((resolve) => {
resolve('Coding Beauty');
});
}
// async, returns Promise too
async function func2() {
return 100;
}
// NOT async, returns NON-Promise
function func3() {
return 'Coding Beauty';
}
Almost every object in JavaScript has a constructor
property that returns a Function
reference to the constructor function that created the object instance.
const num = 2;
const promise = new Promise((resolve) => resolve(100));
const arr = [];
const asyncFunc = async () => 'Coding Beauty';
console.log(num.constructor); // [Function: Number]
console.log(promise.constructor); // [Function: Promise]
console.log(arr.constructor); // [Function: Array]
console.log(asyncFunc.constructor); // [Function: AsyncFunction]
After getting the constructor, we use the Function
instance name
property to get the name of the function.
console.log(num.constructor.name); // Name
console.log(promise.constructor.name); // Promise
console.log(arr.constructor.name); // Array
console.log(asyncFunc.constructor.name); // AsyncFunction
Note that this approach is not very reliable as the value of constructor.name
is not fixed. It could easy be changed in a user-defined class to any value, including 'AsyncFunction'
:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
static name = 'AsyncFunction'
}
const person = new Person('Brandon', 'Evans');
console.log(isAsync(person)); // true (?!)
function isAsync(func) {
return func.constructor.name === 'AsyncFunction';
}
Every Crazy Thing JavaScript Does
A captivating guide to the subtle caveats and lesser-known parts of JavaScript.