Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 是否有不推荐的deferred.callback的替代品? 问题_Node.js_Asynchronous_Promise_Bluebird - Fatal编程技术网

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"))