节点蓝鸟中的 Q.ninvoke 替换
Posted
技术标签:
【中文标题】节点蓝鸟中的 Q.ninvoke 替换【英文标题】:Q.ninvoke replacement in node bluebird 【发布时间】:2015-03-24 18:38:54 【问题描述】:我正在将一个项目从 Q 迁移到 bluebird。 在这个项目中,Q.invoke 被大量使用。
例如在这样的中心方法中:
repo.count = function(entity,query) // entity is a mongoose model
var command = query = entity.find(query).count();
return Q.ninvoke(command, 'exec');
;
重构此代码并返回相同“种类”承诺的最佳蓝鸟方式是什么? 阅读蓝鸟文档,似乎 promisifyAll 似乎是正确方向的一点。现在我有这个工作,但使呼叫阻塞:
repo.count = function*(entity,query)
entity = bluebird.promisifyAll(entity); // this needs to be moved somewhere central
return yield entity.find(query).count();
;
【问题讨论】:
【参考方案1】:我来自谷歌,接受的答案不是我想要的。我正在寻找ninvoke
的通用替代品。
它应该看起来像这样。
Q版:
Q.ninvoke(redisClient, "get", "foo")
蓝鸟版:
Promise.promisify(redisClient.get, context: redisClient)("foo")
【讨论】:
这是迄今为止最好的答案!【参考方案2】:嗯,你可以做几件事。最明显的是令人惊讶的“无”。
当您不通过 exec 回调时,Mongoose 已经返回 Promises/A+ 承诺,您可以将它们同化:
repo.count = function(entity,query) // entity is a mongoose model
return entity.find(query).count().exec(); // return promise
;
您可以安全地将该承诺与 Bluebird 一起使用,它会很高兴地吸收它:
Promise.resolve(repo.count(e, q)); // convert to bluebird promise explicitly
someOtherBBPromise.then(function(query)
return repo.count(entity, query); // `then`able assimilation
);
也就是说,最好是全面地拥有 bluebird 承诺。因为这只蓝鸟有一个非常强大的promisifyAll
,它可以让你立即承诺猫鼬:
var Promise = require("bluebird");
var mongoose = Promise.promisifyAll(require("mongoose"));
// everything on mongoose promisified
someEntity.saveAsync(); // exists and returns bluebird promise
【讨论】:
啊!我喜欢什么都不做!那很简单。还有一个问题:我是否需要在启动时或每次需要时都 promisfyAll mongoose? @AyKarsi 在启动时,使用 bluebird 的承诺会创建 非常 快速函数(与回调版本相比开销接近于零) - 不像 Q 每次 bluebird 都会包装它们实际上为函数动态生成源代码很昂贵,但稍后会使用 JIT 编译器。虽然它是幂等的(多次调用 .promisifyAll 与调用一次的作用相同——它只实际工作一次),所以如果你多次调用它,这没什么大不了的。值得一提的是,bluebird 还与.ninvoke
平行,称为 .fromNode
。
感谢您的澄清!以上是关于节点蓝鸟中的 Q.ninvoke 替换的主要内容,如果未能解决你的问题,请参考以下文章