无论是 ES6 的
我该如何测试一个给定的对象是否为
Promise
,还是 Bluebird 的 Promise
、Q 的 Promise
等等。我该如何测试一个给定的对象是否为
Promise
?Promise
,还是 Bluebird 的 Promise
、Q 的 Promise
等等。Promise
?如果您正在使用Typescript,我想补充一下,您可以使用“类型谓词”功能。只需将逻辑验证包装在返回x是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
(此处为原文,未做翻译)任何将可能同步的value
推入Promise.resolve(value)
以避免比较的做法会使您的代码变成一种本来可以避免的异步。有时您并不希望在那个阶段出现这种情况。您想要在某个早期的解析结果之前知道计算结果,以避免在微任务队列中发生意外。
您可以尝试像这样实现:
var isPromise = x => Object(x).constructor === Promise;
我检查了一些极端情况,看起来它似乎能够正常工作。
isPromise(undefined); // <- false
isPromise(null); // <- false
isPromise(0); // <- false
isPromise(""); // <- false
isPromise({}); // <- false
isPromise(setTimeout); // <- false
isPromise(Promise); // <- false
isPromise(new Promise((v,x) => setTimeout(v,1000,"whatever"))); // <- true
isPromise(fetch('http://example.com/movies.json')); // <- true
我还没有与任何非原生库进行比对,不过现在这有什么意义呢?
在寻找一种可靠的方法来检测异步函数甚至Promise之后,我最终使用了以下测试:
() => fn.constructor.name === 'Promise' || fn.constructor.name === 'AsyncFunction'
Promise
并创建它的实例,这个测试可能会失败。不过这应该适用于你大部分想要测试的内容。 - theramfn.constructor.name === 'AsyncFunction'
是错误的 - 它意味着某些东西是异步函数而不是 Promise - 而且它也不能保证有效,因为人们可以子类化 Promises。 - Benjamin Gruenbaumit('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));
});
function isPromise(value) {
return value && value.then && typeof value.then === 'function';
}
const isPromise = (value) => {
return !!(
value &&
value.then &&
typeof value.then === 'function' &&
value?.constructor?.name === 'Promise'
)
}
对我来说 - 这个检查更好,试一下吧
对于那些试图在TypeScript中实现此操作的人 - 其他提供的解决方案会出错:
if (p instanceof Object && 'then' in p && typeof p.then === 'function') { ... }
在Angular中:
import { isPromise } from '@angular/compiler/src/util';
if (isPromise(variable)) {
// do something
}
J
https://www.npmjs.com/package/is-promise
import isPromise from 'is-promise';
isPromise(Promise.resolve());//=>true
isPromise({then:function () {...}});//=>true
isPromise(null);//=>false
isPromise({});//=>false
isPromise({then: true})//=>false
ES6:
const promise = new Promise(resolve => resolve('olá'));
console.log(promise.toString().includes('Promise')); //true
toString
方法的对象都可以返回一个包含“Promise”的字符串。 - Boghyon Hoffmann'NotAPromise'.toString().includes('Promise') === true
。 - damd
.then
方法,但这并不能确定你得到的是一个 Promise。此时你所知道的只是该对象具有类似 Promise 的.then
方法。 - Scott Offen.then
方法的对象,但这并不意味着它是Promise,也不会像Promise一样运作,并且可能根本没想过要像Promise一样使用它。检查是否存在.then
方法只能告诉你如果对象没有.then
方法,则你没有Promise。相反,存在.then
方法并不一定意味着你有Promise。 - Scott Offen.then
方法。是的,这种方法可能会出现误判,但所有的Promise库都依赖于这种假设(因为它们只能依赖于这个)。我所能想到的唯一替代方案是采用Benjamin Gruenbaum提出的建议并将其运行通过Promise测试套件。但对于实际的生产代码来说,这不太实际。 - JLRisheconst isPromise = v => typeof v === 'object' && typeof v.then === 'function'
可以翻译为“判断变量是否为 Promise 的函数,判断依据是变量的类型为对象并且具有 then 方法”。 - Dominic