无论是ES6承诺还是蓝鸟承诺,Q承诺等等。
我如何测试,看看一个给定的对象是一个承诺?
无论是ES6承诺还是蓝鸟承诺,Q承诺等等。
我如何测试,看看一个给定的对象是一个承诺?
当前回答
如果你正在使用Typescript,我想补充一点,你可以使用“类型谓词”功能。只应该将逻辑验证包装在返回x is Promise<any>的函数中,您不需要进行类型转换。在下面的示例中,c要么是一个promise,要么是我想通过调用c.fetch()方法将其转换为promise的类型之一。
export function toPromise(c: Container<any> | Promise<any>): Promise<any> {
if (c == null) return Promise.resolve();
return isContainer(c) ? c.fetch() : c;
}
export function isContainer(val: Container<any> | Promise<any>): val is Container<any> {
return val && (<Container<any>>val).fetch !== undefined;
}
export function isPromise(val: Container<any> | Promise<any>): val is Promise<any> {
return val && (<Promise<any>>val).then !== undefined;
}
更多信息:https://www.typescriptlang.org/docs/handbook/advanced-types.html
其他回答
要查看给定对象是否为ES6 Promise,可以使用以下谓词:
function isPromise(p) {
return p && Object.prototype.toString.call(p) === "[object Promise]";
}
直接从对象调用toString。prototype返回给定对象类型的原生字符串表示,在本例中为“[object Promise]”。这确保了给定的对象
绕过误报,如..: 具有相同构造函数名称(“Promise”)的自定义对象类型。 给定对象的自写toString方法。 与instanceof或isPrototypeOf相比,可以跨多个环境上下文(例如iframes)工作。
然而,任何特定的宿主对象,其标记通过Symbol被修改。toStringTag,可以返回“[object Promise]”。这可能是预期的结果,也可能不是,这取决于项目(例如,如果有一个自定义的承诺实现)。
要查看该对象是否来自本地ES6 Promise,我们可以使用:
function isNativePromise(p) {
return p && typeof p.constructor === "function"
&& Function.prototype.toString.call(p.constructor).replace(/\(.*\)/, "()")
=== Function.prototype.toString.call(/*native object*/Function)
.replace("Function", "Promise") // replacing Identifier
.replace(/\(.*\)/, "()"); // removing possible FormalParameterList
}
根据本节和规范的这一部分,函数的字符串表示形式应该是:
函数标识符(FormalParameterListopt) {FunctionBody}"
这是上面相应的处理。在所有主流浏览器中,FunctionBody都是[本机代码]。
MDN: Function.prototype.toString
这也适用于多个环境上下文。
如果你在一个异步方法中,你可以这样做,避免任何歧义。
async myMethod(promiseOrNot){
const theValue = await promiseOrNot()
}
如果函数返回promise,它将等待并返回已解析的值。如果函数返回一个值,它将被视为已解析。
如果函数今天没有返回一个承诺,但明天返回一个承诺,或者被声明为异步,那么你将是不受未来影响的。
这是https://github.com/ssnau/xkit/blob/master/util/is-promise.js的代码
!!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
如果一个对象具有then方法,它应该被视为Promise。
在寻找一个可靠的方法来检测Async函数甚至承诺后,我最终使用了以下测试:
() => fn.constructor.name === 'Promise' || fn.constructor.name === 'AsyncFunction'
if (typeof thing?.then === 'function') {
// probably a promise
} else {
// definitely not a promise
}