如何在 JavaScript 中检查函数是否异步

84 阅读4分钟

如何在 JavaScript 中检查函数是否异步

目录

[TOC]

在 JavaScript 中检查函数是否异步

要检查函数是否异步,请访问 constructor.name 函数的属性并检查值是否等于 AsyncFunction

如果比较返回 true ,则该函数是异步的。

const sum = async (a, b) => {
  return a + b;
};
 
if (sum.constructor.name === 'AsyncFunction') {
  // 👇️ this runs
  console.log('✅ function is async');
} else {
  console.log('⛔️ function is NOT async');
}

在函数上访问时,该 constructor 属性返回:

JavaScript 中的每个异步函数都是一个 AsyncFunction 对象。

最后一步是访问 name 构造函数上的属性并检查 AsyncFunction 构造函数是否用于创建函数。

如果条件通过,那么我们就有了一个异步函数。

这种方法适用于箭头和命名函数。

name 如果我们在非异步函数上
访问该属性, "Function" 则会返回该字符串

function example() {}
 
console.log(example.constructor.name); // 👉️ "Functio

不同的构造函数用于创建异步和非异步函数,因此我们可以很容易地判断一个函数是否是异步的。

如果您必须经常这样做,请定义一个可重用的函数。

function isAsyncFunction(func) {
  return func.constructor.name === 'AsyncFunction';
}
 
const sum = async (a, b) => {
  return a + b;
};
 
const subtract = (a, b) => {
  return a - b;
};
 
console.log(isAsyncFunction(sum)); // 👉️ true
console.log(isAsyncFunction(subtract)); // 👉️ false

该函数将另一个函数作为参数, true 如果提供的函数是异步的则返回, false 否则返回。

非异步函数也可能返回一个 Promise

请记住,非异步函数可能会返回一个承诺。

// 👇️ non-async returns Promise
function example() {
  return new Promise(resolve => {
    resolve(100);
  });
}
 
console.log(example()); // 👉️ Promise {}
 
console.log(example.constructor.name); // 👉️ "Function"

该示例显示了一个返回承诺的非异步函数。

了解非异步函数是否返回承诺的唯一方法是调用该函数。

在 JavaScript 中检查函数是否返回 Promise

检查函数是否返回 Promise:

  1. 检查函数是否为 async .
  2. 或者,调用函数并检查它是否返回承诺。
  3. 如果满足任一条件,该函数将返回一个承诺。
// ✅ Promise check
function isPromise(p) {
  if (typeof p === 'object' && typeof p.then === 'function') {
    return true;
  }
 
  return false;
}
 
// ✅ Check if a function's return value is a Promise
function returnsPromise(f) {
  if (
    f.constructor.name === 'AsyncFunction' ||
    (typeof f === 'function' && isPromise(f()))
  ) {
    console.log('✅ Function returns promise');
    return true;
  }
 
  console.log('⛔️ Function does NOT return promise');
  return false;
}
 
// 👇️ Examples
async function exampleAsync() {}
function example() {}
function examplePromise() {
  return new Promise(resolve => {
    resolve(42);
  });
}
 
console.log(returnsPromise(exampleAsync)); // 👉️ true
console.log(returnsPromise(example)); // 👉️ false
console.log(returnsPromise(examplePromise)); // 👉️ true

代码示例中的第一个函数检查传入的值是否为 Promise

function isPromise(p) {
  if (typeof p === 'object' && typeof p.then === 'function') {
    return true;
  }
 
  return false;
}

第二个函数将另一个函数作为参数并检查它的返回值是否是一个 promise。

function returnsPromise(f) {
  if (
    f.constructor.name === 'AsyncFunction' ||
    (typeof f === 'function' && isPromise(f()))
  ) {
    console.log('✅ Function returns promise');
    return true;
  }
 
  console.log('⛔️ Function does NOT return promise');
  return false;
}

语句中的第一个条件 if 检查函数是否为 async

每个 async 函数都会返回一个 Promise,因此如果函数是,我们就知道它会返回一个 Promise。 我们的第二个条件检查传入的值是否是一个函数并调用它, 将结果传递给 isPromise() 函数

总结

检查非异步函数是否返回 Promise 的唯一方法是调用它。请注意,如果函数状态发生变化,则调用该函数可能不安全,例如写入数据库。 有两种方法可以检查函数是否返回 Promise:

  • 检查该函数是否是异步的 – 然后它会返回 100% 的承诺 时间。
  • 检查函数的返回值是否是具有属性的对象 类型函数。

「扩展 」 保证函数始终返回 Promise、

您可以使用 Promise.resolve() 方法来保证该函数将 总是返回一个 Promise。

function example() {
  return 42;
}
 
Promise.resolve(example()).then(value => {
  console.log(value); // 👉️ 42
});

该函数不返回 Promise,但是,我们使用了 Promise.resolve() 方法将值包装在 Promise 中。

如果函数返回 Promise,则代码示例也可以工作。

async function example() {
  return 42;
}
 
Promise.resolve(example()).then(value => {
  console.log(value); // 👉️ 42
});

我们将该函数标记为异步,并且异步函数始终返回 Promise。

无论哪种方式,我们的代码都会按预期工作


Promise.resolve 方法将提供的值解析为 Promise。

  • 如果提供的值是 Promise,则返回 Promise,否则返回 方法返回一个用提供的值解析的 Promise。
  • 如果该值不是 Promise,我们将其包装在一个 Promise 中以便能够使用 .then() 方法。
  • 如果该值是一个 Promise,它会按原样返回,我们仍然可以使用该 .then() 方法。