节点蓝鸟中的 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 替换的主要内容,如果未能解决你的问题,请参考以下文章

蓝鸟承诺未定义?

通过替换写入节点,将写入节点中的过程Nuke写入路径替换为实际路径

替换VB6中的XML节点中的值

XSLT 替换属性值和文本节点中的文本

实战-Cassandra之单令牌替换down节点

使用php替换xml中的特定节点值