Node.js 是否有不推荐的deferred.callback的替代品? 问题
我发现,在我的代码中,当我包含一些库时,通常会出现以下相当详细的模式,这些库为我提供了难以Node.js 是否有不推荐的deferred.callback的替代品? 问题,node.js,asynchronous,promise,bluebird,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);
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()
,这一点过去不那么冗长:
但现在这种模式已经被弃用了(有充分的理由),但我还没有找到一个很好的替代模式。我知道这是:
return Promise.promisify(object.method, object)('foo');
但是,由于传递了上下文
/接收者
,这让人感觉既烦躁又烦躁
我在找什么
我希望有一些东西可以取代旧的延迟。回调
,可能是:
var promise = new Promise;
object.method('foo', promise.callback);
return promise;
或者可能:
return new Promise(function(resolve, reject, callback){
object.method('foo', callback);
});
或者,有人向我指出我一直在“做错事”。好吧,promisify是指在你的应用程序初始化时被调用一次。您可以使用
promisifyAll
一次将整个API转换为promisified API
Promise.promisifyAll(app.auth);
这将允许您在应用程序中的任何时间在app.auth
上使用任何方法作为承诺返回方法:
app.auth.authenticateAsync("local").then(function(res){ // preserves context
// handle result
});
还要注意的是,
promisify
和promisifyAll
比使用new Promise
和自我承诺要快得多,因为它们利用了动态重新编译技术和其他各种优化,所以最好使用它们(但仅在初始化时).从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"))
嗨,本杰明,谢谢你的回答,但这不是我想要的。我在任何可能的情况下都使用
promisifyAll
,但有时库会给我一些它们没有公开构造函数或原型的对象(想想:function(){return{…}}
)。在这种情况下,我需要即时的承诺。我很抱歉没有在我的问题中具体说明这一点。我将在中编辑它。在这种情况下,没有-没有直接替换您使用的图案。您可以继续使用.defer()
一段时间,当/如果删除它时,您可以填充它。他的全部目的是避免.defer(),因为有人不赞成它(有一个很好的理由):p您的想法很有趣,尽管您的实现讽刺地使用了Promise.defer
。我想我会使用这个解决方案(使用一个更好的实现,然后我会编辑到你的答案中)?我在你的个人资料中看到了一个链接,可能你就是这篇文章的作者article@Avaqbluebird 2.9.0我刚刚注意到这是我在文档中的示例代码。我感到荣幸。这是我通过堆栈溢出问题对Bluebird所做的贡献。哦,我也刚刚意识到你是佩卡。哎呀。我猜你完全正确地使用了承诺。推迟我现在就闭嘴$我不知道你是否注意到了,但是Petka(Esailija)已经为你的用例向库中添加了Promise.fromNode
——无论如何,这是你应该在你的用例中使用的。我注意到了。请参见下面的对话(Esailija的回答):
return Promise.fromNodeFunction(object.method.bind(object, "foo"))