【问题标题】:JavaScript Promises mongoose and bluebird missing catch and failJavaScript Promises mongoose 和 bluebird 丢失捕获和失败
【发布时间】:2014-07-11 20:22:37
【问题描述】:

我已经开始使用 Promise,我使用 Node.js Mango(与 mongoose)和 bluebird.. 我遇到的问题是由于某种原因,当我将猫鼬调用与返回承诺的函数链接起来时(我假设这是返回和链接的正确方法)然后我得到:

typeError: Object #<Promise> has no method 'fail'

如果我更改失败捕获,那么我会遇到同样的问题:

typeError: Object #<Promise> has no method 'catch'

我所做的是使用完全失败并捕获的函数(null,函数)模式。 但是 catch / fail 更具可读性。任何线索为什么我会得到这个以及我应该如何解决这个问题?

这是代码块的示例。

User.findOne({ 'email' :  user_email }).exec()
 }).then (promisedTransformUserSchemaToFrontendObjectWithProjectMapping)
   .then (function (feUser) {
       return new Promise(function (resolve, reject) {
          res.json(feUser);
          return resolve(feUser);
      });
   }).fail/catch  (function (err) {
      console.log(err);
      sendError(res,"failed to get user",err);
   });

这里是堆栈跟踪:

TypeError: Object #<Promise> has no method 'catch'
    at module.exports.app.put.User.update.email (app\controllers\router.js:165:16)
    at callbacks (node_modules\express\lib\router\index.js:164:37)
    at isLoggedIn (app\controllers\router.js:741:10)
    at callbacks (node_modules\express\lib\router\index.js:164:37)
    at param (node_modules\express\lib\router\index.js:138:11)
    at param (node_modules\express\lib\router\index.js:135:11)
    at pass (node_modules\express\lib\router\index.js:145:5)
    at Router._dispatch (node_modules\express\lib\router\index.js:173:5)
    at Object.router (node_modules\express\lib\router\index.js:33:10)
    at next (node_modules\express\node_modules\connect\lib\proto.js:193:15)

【问题讨论】:

  • 你能分享堆栈跟踪吗?
  • 不要使用mongoose返回的promises,只使用promisifyAll并独占使用*Async方法
  • new Promise 位也受到延迟反模式的影响
  • @Esailija 是的,可能只是.tap(res.json)
  • @Esailija 为什么不使用异步方法,为什么新的 Promise 是反模式?

标签: javascript node.js mongodb mongoose promise


【解决方案1】:

mongoose 4.1+ 维护者建议:

es2015 (es6):

require('mongoose').Promise = Promise;

蓝鸟:

require('mongoose').Promise = require('bluebird');

问:

require('mongoose').Promise = require('q').Promise;

【讨论】:

  • 为什么只有 +3 ?使用 require('mongoose').Promise = Promise;轻松添加支持,让我的世界变得更美好。非常感谢!!
【解决方案2】:

我不知道 moongose,但一般来说,fail 或 catch 之类的函数是方便快捷的方法,而不是 Promise 规范的一部分。因此,库不需要让它们符合承诺。显然在你的情况下他们不在那里。

您可以使用then(successHandler, rejectionHandler) 实现相同的功能。

为了处理 promise 的拒绝,你可以重写你的代码如下:

User.findOne({ 'email' :  user_email }).exec()
 }).then (promisedTransformUserSchemaToFrontendObjectWithProjectMapping)
   .then (function (feUser) {
       return new Promise(function (resolve, reject) {
          res.json(feUser);
          return resolve(feUser);
      });
   }).then (undefined, function (err) {
      console.log(err);
      sendError(res,"failed to get user",err);
   });

【讨论】:

  • 我认为 catch 很好,至少 MDN 在文档中有它以及 Promise.all 拒绝和解决。
【解决方案3】:

bluebird 文档中显示了另一种方法:

https://github.com/petkaantonov/bluebird/blob/master/API.md#promiseresolvedynamic-value---promise

你可以在 bluebird 的 Promise.resolve() 中包装 mongoose 承诺,你会得到一个 bluebird 承诺。

 Promise.resolve(User.findOne({ 'email' :  user_email }).exec())
 .then (promisedTransformUserSchemaToFrontendObjectWithProjectMapping)
   .then (function (feUser) {
          res.json(feUser);
          return feUser;
   }).fail/catch  (function (err) {
      console.log(err);
      sendError(res,"failed to get user",err);
   });

【讨论】:

    【解决方案4】:

    似乎问题在于混合了两种类型的承诺(蓝鸟和猫鼬)..

    一旦我在 db 对象上使用了 promsifyAll,catch 就开始起作用了..

    // promisify all model using mongoomise..
    require('../../mongoomise').promisifyAll(mongoose, require('bluebird'))

    【讨论】:

    • @MuhammadUmer 试试我添加的这段小代码,希望对您有所帮助。
    • 如果您使用 mongoose 4.1.0(2015-07-24 发布)或更高版本,则不应将 promisify 与 mongoose 一起使用。应该首选 Jason Sebring 的答案(我认为应该更改标记的解决方案)。 mongoosejs.com/docs/…
    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    相关资源
    最近更新 更多