我有一个函数,它需要函数或类的单个参数,并且我必须对两者执行不同的操作。
示例伪代码:
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 库提供支持,因此开发人员可以传递他们已经使用的任何实现,而不必执行任何解决方法或使用我的实现。请记住,我不仅仅谈论现代虚拟机中的 native 实现,而且还针对 other implementations 。如果开发人员不想(不想)使用 Promise 库,可调用函数选项可以作为后备方案。我希望这个解释有一定道理。
根据我的尝试,我总是得到类和可调用函数相同的结果,因为 JavaScript 中的类只是函数。我能做的唯一解决方法是检查callback.length
,但此功能非常脆弱,并且很可能在任何实际用例中崩溃。
最佳答案
任意回调函数和构造函数之间实际上没有任何区别。
ES6 将在这里添加一些区别(例如,不为箭头函数提供 .prototype
属性),但这些都不可靠。
构造函数和“普通”函数之间唯一真正的区别是它们的原型(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()
成为实例而不是原型(prototype)方法。另外不要忘记 Promise
构造函数尚未标准化(ES6 中有,但 Promises/A+ 中没有)。
比使用 Promise
构造函数模式更好的主意是 Promise.resolve
。您只需构造一个任意的 thenable ,然后它就会被每个 Promise 实现同化。您甚至不需要将该解析器作为参数提供,您应该在没有回调函数参数的情况下返回thenable。然后,您的消费者可以将对 API 的所有调用封装在他们最喜欢的库的 Promise.resolve(…)
中。
这就是 Promise 互操作性的最初设计方式,因此它绝对有效。
关于javascript - 确定参数是类(A+ Promise 实现)还是可调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30294946/