使用 JavaScript 检查值是否为 Promise

检查 Value 是否是 JavaScript 中的 Promise

Check if a Value is a Promise using JavaScript

要检查一个值是否为 promise,请检查该值的类型是否为对象并且是否具有名为then函数类型的属性,例如
typeof p === 'object' && typeof p.then === 'function'. 如果两个条件都返回true,则该值是一个承诺。

索引.js
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 个条件。

两个条件都必须返回真值才能使if块运行。

所有的承诺都有一个类型object,所以这是我们首先要检查的。

索引.js
const p1 = new Promise(resolve => { resolve(10); }); console.log(typeof p1); // 👉️ "object"

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

承诺有一个.then().catch()方法。

这种方法称为鸭子类型。我们基本上说 – “如果值是一个对象并且具有这些特定的属性/方法,那么它一定是一个承诺”。

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

索引.js
function isPromise(p) { if (typeof p === 'object' && typeof p.then === 'function') { return true; } return false; } console.log(isPromise({then: () => {}})); // 👉️ true

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

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

索引.js
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
索引.js
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有一种object. 这是 JavaScript 中的一个旧错误,由于向后兼容性问题尚未修复。
索引.js
console.log(typeof null); // 👉️ "object"

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

索引.js
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()and的方法catch(),但不是实际的承诺。

您的用例可能不需要这种过度设计的解决方案。检查具有该then方法的对象可能会很好。关于您希望解决方案的鲁棒性,这是个人偏好的问题。