【问题标题】:Using Promises in Mongoose Routes在 Mongoose 路由中使用 Promise
【发布时间】:2023-03-08 21:45:01
【问题描述】:

我理解 JavaScript 中的 Promise 或至少我认为我理解(​​如果我错了,请纠正我)。

创建承诺:

var promise = new Promise(function(resolve, reject){
  // do something async here

  if(itWorked){

    resolve();

  }else {

    reject();
  }

});

使用承诺:

promise.then(function(result){

},function(err){

});

我有一个基于 MEAN Stack 的应用程序,我的一些 mongoose 路由正在成为回调地狱。我想摆脱猫鼬路由中的回调并使用 Promises 处理它们。但我似乎无法弄清楚该怎么做。

例如:

app.get('/users', function(req, res){

  User.findOne(_id, function(err, user){
      if(err)
         console.log(err)
      else if(user){

         Receipt.findOne(user.bookName, function(err, book){
           if(err)
            console.log(err)

           else if(book){
             // again do something here
          }  
       })
     }
   })
});

在上面的示例中,您可以看到代码变得越来越难以阅读和维护。我如何在这里使用 Promises 来改进我的代码?

【问题讨论】:

    标签: javascript node.js mongodb mongoose promise


    【解决方案1】:

    好的,首先您使用的是mongoose 对吗?

    User 是您的猫鼬模型,它响应诸如findOne(query)findOneAndUpdate(query, update, opts) 等方法。

    调用这些方法中的任何一个后,调用方法exec(),它会返回一个查询。

    查询并不完全是 Promise,您需要指定 Mongo 将使用哪些 Promise。在这里我建议使用原生的,所以在你的项目中添加这一行:

     const mongoose = require('mongoose')
     mongoose.Promise = Promise
    

    现在,这条指令正在返回一个 Promise,很好!

    User.findOne(q).exec()
    

    您现在可以使用您的逻辑创建一个 Promise 链,例如:

     return User
         .findOne(_id)
         .exec()
         .then((user) => {
           return Receipt
             .findOne({ bookName: user.bookName })
             .exec()
           })
         .then((receipt) => {
                // example
                return res.status(200).json(receipt)
             }))
         })
    

    提示:我建议创建辅助方法以使代码更加简洁:

    /** @return {Promise} */
    function findUser(id) {
      return User.findOne(id).exec()
    }
    
    /** @return {Promise} */
    function findReceipt(bookName) {
      return Receipt.findOne({ bookName }).exec()
    }
    
    // example
    function f(req, res) {
      const userId = req.get('id')
    
      return findUser(userId)
        .then((user) => findReceipt(user.bookName))
        .then((receipt) => res.status(200).json(receipt))
        .catch((err) => res.status(500).json(null))
    }
    
    // register your handler
    app.get('/book', f)
    

    【讨论】:

    • 非常感谢您的回答。我有几个问题要澄清一些概念。在mongoose.Promise = Promise 行中,您是否将本机 ES6 承诺库插入到猫鼬中?当_findUser 承诺返回时,then 函数会运行吗?我猜returning a promise这个词的意思是_findUser函数是否有resolvedrejected。我说的对吗?
    • 没错,mongoose.Promise = Promise 告诉 mongoose 使用原生 ES6 承诺;链接承诺:_findUser() 是一项繁重的任务,总有一天会返回预期的用户,你解决了user 你可以开始一个新任务(你注意到返回了吗?)_findReceipt()。这也是一项繁重的任务,将返回receipt您已解决receipt 您已准备好返回您的回复。如果这些任务中的 ANY 引发错误,您将执行 catch 语句
    • 非常感谢您的解释。我现在基本明白了。出于某种原因,我发现承诺很难理解。
    • 你会勾选这个答案吗?
    猜你喜欢
    • 2019-06-18
    • 2018-03-07
    • 2018-09-09
    • 2016-11-27
    • 2017-07-01
    • 1970-01-01
    • 2019-02-08
    • 2016-01-02
    • 1970-01-01
    相关资源
    最近更新 更多