Wrapper函数,无论函数参数如何都返回promise

时间:2017-03-13 09:29:34

标签: javascript angularjs promise

在我的项目中,我有一个场景,我有不同类型的函数和不同的参数。其中一个参数包含回调函数。并且还存在函数没有任何参数的情况。如下图所示:

abc(string, function, number)
aaa(function, string)
bcd()
xyz(function)
cda(string, number, function, string)

我需要编写一个函数,不管上面函数的不规则性,函数都应该返回一个promise。

示例:

// Assume $q has been injected
var defer = $q.defer();
function returnPromise(functionName, functionArgumentsInArray){
    defer.resolve(window[functionName].apply(null, functionArgumentsInArray));
    return defer.promise;
}

如您所见,上述函数不解析回调函数,只解析函数。

注意:函数最多只有一个函数参数或者没有。

我知道可以针对每种情况单独完成,如下所示:

function returnPromise(){
    var defer = $q.defer();
    abc("hey", function() {
        defer.resolve(arguments);
    }, 123);
    return defer.promise;
}

但我正在为所有这些功能寻找一个通用的包装器。

1 个答案:

答案 0 :(得分:3)

我认为你正在寻找像

这样的东西
const cbPlaceholder = Symbol("placeholder for node callback");
function wrap(fn) {
    return function(...args) {
        return $q((resolve, reject) => {
            function nodeback(err, result) {
                if (err) reject(err);
                else resolve(result);
            }
            for (var i=0; i<args.length; i++)
                if (args[i] === cbPlaceholder) {
                    args[i] = nodeback;
                    break;
                }
            const res = fn.apply(this, args);
            if (i == args.length) // not found
                resolve(res);
        });
    };
}

您可以将其用作

const abcPromised = wrap(abc);
abcPromised("hey", cbPlaceholder, 123).then(…)

另请查看How do I convert an existing callback API to promises?。通常,当所有promisified函数遵循约定将回调作为其最后一个参数时,您不应该需要占位符。