我有一个函数,它需要一个函数或一个类的单个参数,我必须对这两个参数做不同的操作。
伪代码示例:
function myFunction(callback) {
if ( /* callback is a Promise class */ ) {
return new callback(function (resolve, reject) {
// logic
resolve();
});
} else if ( /* callback is a callable function */ ) {
// logic
callback(); // Realistically this would not be called at the end of logic block.
} else {
// throw error
}
}
我想为实现A +标准的任意Promise库提供支持,因此开发人员可以传递他们已经使用的任何实现,而不必执行任何变通办法或使用我的实现。请记住,我不是在谈论现代虚拟机中的本机实现,而是还针对other implementations。如果开发人员不(想)使用Promise库,则可调用函数选项作为后备。我希望这个解释有道理。
从我的尝试开始,我总是为类和可调用函数得到相同的结果,因为JavaScript中的类只是函数。我能够做的唯一解决方法是检查callback.length
,但是这个功能非常脆弱,很可能在任何实际用例中都会中断。
答案 0 :(得分:3)
任意回调函数和构造函数之间没有任何区别。
ES6会在这里添加一些区别(例如,不给箭头函数.prototype
属性),但这些都不可靠。
构造函数与"正常"之间唯一真正的区别功能是他们的原型。如果您专门针对Promise实现,那么所有严重的库都将在那里使用.then()
方法。
所以你可以使用
if (typeof callback == "function")
if (callback.prototype && typeof callback.prototype.then == "function")
// looks like a Promise constructor
else
// an ordinary function
当然,这对100%可想象的案例都不起作用。可能有其他类具有then
方法,并且有Promises / A +一致的实现使.then()
成为实例而不是原型方法。另外,请不要忘记Promise
构造函数尚未标准化(它在ES6中,但在Promises / A +中没有)。
比使用Promise
构造函数模式更好的想法是Promise.resolve
。你只是构造一个任意的,然后被每个承诺实现同化。您甚至不需要将解析器作为参数给出,您应该在没有回调函数参数的情况下返回该值。然后,您的消费者可以在他们最喜欢的图书馆的Promise.resolve(…)
中将所有对您的API打包。
这首先是Promise互操作性的设计方式,因此它绝对有效。