我发现当我包含给我很难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);
});
或者,有人向我指出我做过错误"一直以来。
答案 0 :(得分:1)
嗯,promisify意味着在您的应用初始化时调用一次。您可以使用promisifyAll
一次将整个API转换为有希望的API。
Promise.promisifyAll(app.auth);
这将允许您在应用程序的任何时候在app.auth
上使用任何方法作为承诺返回方法:
app.auth.authenticateAsync("local").then(function(res){ // preserves context
// handle result
});
另请注意,promisify
和promisifyAll
明显快于使用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"))