在 Mongoose 路由中使用 Promise
Posted
技术标签:
【中文标题】在 Mongoose 路由中使用 Promise【英文标题】:Using Promises in Mongoose Routes 【发布时间】:2016-12-16 02:23:08 【问题描述】:我理解 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】:好的,首先您使用的是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
函数是否有resolved
或rejected
。我说的对吗?
没错,mongoose.Promise = Promise
告诉 mongoose 使用原生 ES6 承诺;链接承诺:_findUser()
是一项繁重的任务,总有一天会返回预期的用户,当你解决了user
你可以开始一个新任务(你注意到返回了吗?)_findReceipt()
。这也是一项繁重的任务,将返回receipt
。 当您已解决receipt
您已准备好返回您的回复。如果这些任务中的 ANY 引发错误,您将执行 catch
语句
非常感谢您的解释。我现在基本明白了。出于某种原因,我发现承诺很难理解。
你会勾选这个答案吗?以上是关于在 Mongoose 路由中使用 Promise的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 jQuery .ajax() 路由的 .done() 方法没有在我的 NodeJS、Express 和 Mongoose 项目中触发?
在多个文件中使用 Mongoose Schema (mongoose)
如何使用 Mongoose 在 AngularJS 中创建 PUT 函数
基于 GET 参数的 Express/Mongoose REST API 路由