javascript - 确定参数是类(A+ Promise 实现)还是可调用函数

标签 javascript promise

我有一个函数,它需要函数或类的单个参数,并且我必须对两者执行不同的操作。

示例伪代码:

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/

相关文章:

当从另一个服务调用服务时,Angular 6/Typescript HTTP post 请求返回未定义

javascript - 从 Dexie promise 中获取值(value)

javascript - window.onload Javascript,具有接收参数的函数?

javascript - 自动滚动到 div 的底部不能在 android 中使用 Html

javascript - Qt5 和 QML : How to automatically input username and password using WebEngine Quick Nano Browser

javascript - 您可以将参数传递给函数而不立即调用它吗?

javascript - 根据响应跳过一系列 promise 中的 jQuery promise

javascript - 为 promise 中的对象赋值

javascript - 如何在使用格式为 `export` 的 Vite 构建时保持根级别 `esm`

javascript - 递归 Steam API 调用不会终止