【问题标题】:Node.js deferred promisify + mongooseNode.js 延迟 promisify + mongoose
【发布时间】:2012-08-08 09:35:30
【问题描述】:

有人使用过 nodejs 模块“deferred”和“mongoose”吗?我试图让 deferred.promisify 方法在猫鼬模型的功能上工作,这样我就可以轻松地将它们链接起来,但遇到了一些麻烦。具体来说,我想承诺findfindById 函数,这样我就可以通过ObjectID 链接查找另一个文档引用的一个文档。

这是我得到的:https://gist.github.com/3321827

但是,这似乎不太理想,因为 getAppPermissionsgetApplication 函数似乎只是 mongoose 模型的 findfindById 方法的包装器。

我尝试只将函数传递给 promisify,但我收到一个关于 Object #<Object> has no method '_applyNamedScope' 的错误,这似乎是因为 this 不再绑定到正确的对象。也许我需要使用 underscore.bind?有没有人在这方面取得任何成功,还是我应该坚持现在的工作?

【问题讨论】:

  • Node/V8实现了Function.prototype.bind,所以不需要Underscore的绑定;例如,MyModel.find.bind(MyModel)

标签: javascript node.js mongoose deferred


【解决方案1】:

Mariusz 的回答非常接近。以下是在这种特殊情况下最终对我有用的方法,希望其他人可以从中学习:

// I put this in my model file so I didn't have to worry about repeating it
var userProto = mongoose.model('User');

userProto.pFind = deferred.promisify(userProto.find);
userProto.pFindOne = deferred.promisify(userProto.findOne);

【讨论】:

    【解决方案2】:

    您可能没有正确地将上下文传递给方法,正确的做法是直接在 Mongoose 原型上提供方法的承诺版本:

    // I assume that methods you're using are set on mongoose.Model,
    // but be sure to check, maybe, they're using some other prototype (!)
    var promisify = require('deferred').promisify;
    var modelProto = mongoose.Model.prototype;
    modelProto.pFind = promisify(modelProto.find);
    modelProto.pFindById = promisify(modelProto.findById);
    
    // After that you may use promisified methods directly:
    app.get('/apps', requireLogin, function (req, res) {    
      AppPermissions.pFind({ user: req.user.id, valid: true })
        .map(function (permission) {
          return ApplicationRecord.pFindById(permission.application)(
            function (application) {
              application.permission = permisson;
              return application;
            }
          );
        }).end(function (applications) {
          res.render('applist', { applications: applications });
        }, null);
    });
    

    你也可以避免污染原型,间接使用方法:

    var promisify = require('deferred').promisify;
    var modelProto = mongoose.Model.prototype;
    var pFind = promisify(modelProto.find);
    var pFindById = promisify(modelProto.findById);
    
    app.get('/apps', requireLogin, function (req, res) {    
      pFind.call(AppPermissions, { user: req.user.id, valid: true })
        .map(function (permission) {
          return pFindById.call(ApplicationRecord, permission.application)(
            function (application) {
              application.permission = permisson;
              return application;
            }
          );
        }).end(function (applications) {
          res.render('applist', { applications: applications });
        }, null);
    });
    

    【讨论】:

    • 谢谢 - 这实际上不是答案(请参阅我自己的答案),但它确实帮助我找到了正确的方向!
    • 你的答案真的一样,我只是不知道如何得到 right 原型对象(没有尝试运行代码)。无论如何,很好,它为你解决了:)
    猜你喜欢
    • 2014-04-04
    • 2012-08-27
    • 2021-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2016-05-11
    相关资源
    最近更新 更多