是否有已弃用的deferred.callback的替代品?

时间:2015-01-21 17:32:58

标签: node.js asynchronous promise bluebird

问题

我发现当我包含给我很难promisify的对象的库时,我的代码中通常会出现以下相当冗长的模式:

var object = crummyLibrary.create();
return new Promise(function(resolve, reject){
  object.method('foo', function(err, bar){
    if(err){
      reject(err);
    }else{
      resolve(bar);
    }
  });
});

以前使用Promise.defer()

的情况较为冗长
var deferred = Promise.defer();
object.method('foo', deferred.callback);
return deferred.promise;

但现在已经弃用了(有充分理由),但我还没有找到一个很好的替代品。我知道有这个:

return Promise.promisify(object.method, object)('foo');

但是由于context / receiver的传递,它感觉很乱,而且非常狡猾。

我正在寻找

我希望有一些东西可以取代旧的deferred.callback,可能是这样的:

var promise = new Promise;
object.method('foo', promise.callback);
return promise;

或者可能:

return new Promise(function(resolve, reject, callback){
  object.method('foo', callback);
});

或者,有人向我指出我做过错误"一直以来。

2 个答案:

答案 0 :(得分:1)

嗯,promisify意味着在您的应用初始化时调用一次。您可以使用promisifyAll一次将整个API转换为有希望的API。

Promise.promisifyAll(app.auth);

这将允许您在应用程序的任何时候在app.auth上使用任何方法作为承诺返回方法:

app.auth.authenticateAsync("local").then(function(res){ // preserves context
    // handle result
});

另请注意,promisifypromisifyAll明显快于使用new Promise并自我宣传,因为它们使用动态重新编译技术和其他各种优化,因此最好使用它们(但仅限于在初始化时)。

答案 1 :(得分:1)

从2.9.0开始,Bluebird附带.fromNode方法,以便为行为不当的库提供更快的动态默认:

Promise.fromNode(object.method.bind(object, "foo"))

我想可以实现以下内容:

return Promise.fromNodeFunction(function(callback){
  object.method('foo', callback);
});

只需要考虑更好的名字,而不是那么冗长......

自己实施:

Promise.fromNodeFunction = function(resolver) {
    var d = Promise.defer();
    try {
        resolver(d.callback);
    } catch (e) {
        d.reject(e);
    }
    return d.promise;
};

这是最优选的,因为它现在是3行但是使用箭头功能它是一个单行:

return Promise.fromNodeFunction(callback => object.method("foo", callback))

它也适用于bind:

return Promise.fromNodeFunction(object.method.bind(object, "foo"))