确定参数是否为类(A + promise实现)或可调用函数

时间:2015-05-18 04:07:46

标签: 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库提供支持,因此开发人员可以传递他们已经使用的任何实现,而不必执行任何变通办法或使用我的实现。请记住,我不是在谈论现代虚拟机中的本机实现,而是还针对other implementations。如果开发人员不(想)使用Promise库,则可调用函数选项作为后备。我希望这个解释有道理。

从我的尝试开始,我总是为类和可调用函数得到相同的结果,因为JavaScript中的类只是函数。我能够做的唯一解决方法是检查callback.length,但是这个功能非常脆弱,很可能在任何实际用例中都会中断。

1 个答案:

答案 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互操作性的设计方式,因此它绝对有效。