使用 Strongloop 环回实现 Q

Implementing Q with Strongloop Loopback

Q 是 "supporting module" of loopback。我不完全确定这意味着什么,但我假设它至少意味着可以将 Q 与环回的持久模型函数一起使用,例如 find()findOne()。我想知道如何正确设置如下内容:

app.models.Question.findOne({
    where: {name: "My Question"}
}, function (err, result) {
    throw err if err
}).then(function () {
    console.log("success")
})

我已经使用 NPM 在我的项目目录中安装了 Q,但据我所知,app.models.Question.findOne() 仍然是 return 未定义的,而不是一个可用的 Q promise。

根据loopback docs,使用Q,

If a function cannot return a value or throw an exception without blocking, it can return a promise instead.

在这种情况下,我需要做什么才能环回 return 承诺?

LoopBack 查询此时不return 承诺。请 post 在 LoopBack 存储库中提出功能请求以提醒我们(当然是在阅读 https://github.com/strongloop/loopback/wiki/Issues 之后)。但是,我确实相信 ES6 承诺在路线图上。

也就是说,您可以创建自己的承诺,然后 return 改为:

var deferred = Q.defer();
app.models.Question.findOne({
  where: {
    name: 'My Question'
  }
}, function(err, result) {
  if (err) return deferred.reject(err);
  deferred.resolve(result);
});
return deferred.promise;

注意 我还没有测试过这个,但它应该符合这些原则。有关详细信息,请参阅 https://github.com/kriskowal/q#using-deferreds

经过更多的实验,我最终实现了@superkhau 方法的变体。 (请原谅咖啡脚本)。

app.wrapper = (model, fn, args)->
    deferred = Q.defer()
    args.push((err, result)->
        throw err if err
        deferred.resolve(result)
    )
    app.models[model][fn].apply(app.models[model], args)
    return deferred.promise

在引导脚本中使用该模块,您可以像这样在任何现有环回模型的方法上调用包装器:

app.wrapper("Question", "findOne", [{
    where: {
        name: {'My Question'}
    }
}]).then((question)->
    console.log("Success!")
    console.log(question)
)

请注意,包装器采用三个参数 - 模型名称、函数名称和参数数组。 arguments 数组应该是函数在正常调用时将采用的参数数组。

对 promises 的支持正在进入核心,请参阅:https://github.com/strongloop/loopback/issues/418

我是 Q.ninvoke method of the popular Q promise library 的超级粉丝,事实证明它有一个类似于@Morslamina 解决方案的方法签名,但没有 having-to-write-it-myself 部分。如果你像我一样是个懒惰的编码员,那就太好了。

loopback = require 'loopback'
q = require('q').ninvoke

app = module.exports = loopback()

app.get '/apples/:id', (res, req) ->
  q(app.models.Apple, 'findById', req.params.id).done (apple) ->
    res.render 'apple', apple: apple

在 promises 正式登陆 Loopback 之前,这是一个不错的方法。