在Mongoose路由中使用Promise

时间:2016-08-09 21:41:27

标签: javascript node.js mongodb mongoose promise

我理解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来改进我的代码?

1 个答案:

答案 0 :(得分:3)

好的,首先你正在使用mongoose吗?

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

在调用任何这些方法之后,调用返回Query的方法exec()

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

 const mongoose = require('mongoose')
 mongoose.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)
         }))
     })

提示:我建议创建aux方法,以使代码更清晰:

/** @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)