我如何判断一个对象是否是一个Promise?

无论是ES6承诺还是蓝鸟承诺,Q承诺等等。

我如何testing以查看给定对象是否是Promise?

承诺库如何决定

如果它有一个.then函数 – 这是唯一的标准承诺库使用。

Promises / A +规范有一个叫做then的概念,它基本上是“一个具有then方法的对象”。 承诺将会并且应该用当时的方法来吸收任何东西 。 所有你提到的承诺实现都这样做。

如果我们看看规范 :

2.3.3.3如果then是一个函数,就用这个x来调用它,第一个参数是resolvePromise,第二个参数是rejectPromise

它也解释了这个devise决定的基本原理:

这样的处理可以允许promise实现互操作,只要它们公开Promise / A +的方法即可。 它还允许Promises / A +实现用合理的方法“吸收”不一致的实现。

你应该如何决定

你不应该 – 而是在Q中调用Promise.resolve(x)Q(x) ),它总是将任何值或外部值转换成可信任的承诺。 比自己执行这些检查更安全,更简单。

真的需要确定吗?

你总是可以通过testing套件运行它:D

检查某些东西是否是不必要的,使代码复杂化,只需使用Promise.resolve

 Promise.resolve(valueOrPromiseItDoesntMatter).then(function(value) { }) 

这是我原来的答案, 在规范中被批准为testing承诺的方式:

 Promise.resolve(obj) == obj 

这是有效的,因为algorithm明确要求Promise.resolve必须返回传入的确切对象,当且仅当它是由spec的定义的承诺。

我在这里有另外一个答案,这个答案曾经这样说过,但当时它不适用于Safari,我把它改成了别的东西。 那是一年前,即使在Safari上也可以正常工作。

我会编辑我原来的答案,只是觉得不对,因为现在有更多的人投票支持修改后的答案。 我相信这是更好的答案,我希望你同意。

更新:这不再是最好的答案。 请select我的其他答案 。

 obj instanceof Promise 

应该这样做。 请注意,这可能只能与本地es6承诺可靠地工作。

如果你正在使用垫片,承诺库或其他任何冒充类似promise的东西,那么testing一个“thenable”(任何带有.then方法的东西)可能更合适,如其他答案所示。

 if (typeof thing.then === 'function') { // probably a promise } else { // definitely not a promise } 

这里是代码formshttps://github.com/ssnau/xkit/blob/master/util/is-promise.js

 !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; 

如果一个对象有一个then方法,那么应该把它当作一个Promise

 it('should return a promise', function() { var result = testedFunctionThatReturnsPromise(); expect(result).toBeDefined(); // 3 slightly different ways of verifying a promise expect(typeof result.then).toBe('function'); expect(result instanceof Promise).toBe(true); expect(result).toBe(Promise.resolve(result)); }); 

要查看给定的对象是否是本地ES6 Promise ,我们可以使用这个谓词:

 function isPromise (x) { return x && Object.prototype.toString.call(x) === "[object Promise]" } 

直接从Object.prototype调用toString返回给定对象types的本地string表示 ,在我们的例子中是"[object Promise]" 。 这确保了给定的对象

  • 绕过
    • 具有相同构造函数名称(“Promise”)的自定义对象types。
    • 自我重写toString方法给定的对象。
  • 跨越多个环境上下文(例如iframe) 与instanceof