使用 JavaScript 检查值是否为 Promise

要检查一个值是否为 promise,请检查该值的类型是否为对象并且是否具有名为 then 的函数类型的属性,例如 typeof p === ‘object’ && typeof p.then === ‘function’。 如果两个条件都返回 true,则该值是一个 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

我们使用逻辑与 && 运算符来链接 2 个条件。

所有的 promise 都有一个对象类型,所以这是我们首先要检查的。

const p1 = new Promise(resolve => {
  resolve(10);
});

console.log(typeof p1); // ?️ "object"

然后我们访问对象的 then 属性并检查它是否具有函数类型。

Promise 有 .then() 和 .catch() 方法。

如果有人传入一个带有函数 then 属性的普通对象,则此条件检查将失败:

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

  return false;
}

console.log(isPromise({then: () => {}})); // ?️ true

我们满足了这两个条件并得到了误报。

为了使解决方案更健壮,我们还可以添加对 catch 方法的检查。

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

  return false;
}

console.log(isPromise({then: () => {}})); // ?️ false

我们添加了一个条件来检查对象是否也包含 catch 方法。

如果有人传入 null 值,该函数将返回错误。

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));
console.log(typeof null); // ?️ "object"

我们可以添加一个条件来检查传入的值是否不为空。

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

我们的用例可能不需要这种过度设计的解决方案。 检查具有 then 方法的对象可能会很好。 我们希望解决方案的稳健程度取决于个人喜好。