How to Check If Function Returns a Promise in JavaScript

Last updated on January 11, 2023
How to Check If Function Returns a Promise in JavaScript

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';
}

See also