Mongoose中findById查询失效,请求协助将回调风格代码转换为Promise形式
Mongoose中findById查询失效,请求协助将回调风格代码转换为Promise形式
嘿,我完全懂你现在的困扰——Mongoose现在确实更推崇用Promise或者async/await来替代传统的回调写法,不仅是官方推荐的方向,还能避免嵌套回调带来的“回调地狱”,代码可读性和可维护性都会好很多。我来帮你把这段代码转换成更规范的Promise风格,给你两种常用的实现方式参考~
首先先回顾下你原来的回调风格代码:
module.exports.create = function(req, res){ Post.findById(req.body.post, function(err, post){ if (post){ Comment.create({ content: req.body.content, post: req.body.post, user: req.user._id }, function(err, comment){ // handle error post.comments.push(comment); post.save(); res.redirect('/'); }); } }); }
这段代码的问题不仅是回调嵌套,还缺少了完整的错误处理(比如findById查询失败、评论创建失败、帖子保存失败的情况都没处理),而且现在Mongoose对回调的支持已经逐渐弱化了。下面是两种转换方案:
方案一:使用Promise链式调用
Mongoose的所有模型方法(比如findById、create)如果不传递回调函数,本身就会返回一个Promise,我们可以用.then()来链式处理异步操作,用.catch()统一捕获错误:
module.exports.create = function(req, res) { Post.findById(req.body.post) .then(post => { if (!post) { // 找不到对应帖子时的处理 return res.status(404).send('目标帖子不存在'); } // 创建评论,返回Promise供下一个then处理 return Comment.create({ content: req.body.content, post: req.body.post, user: req.user._id }); }) .then(comment => { // 重新查询帖子(链式调用中需重新获取post对象) return Post.findById(req.body.post) .then(post => { post.comments.push(comment); return post.save(); }); }) .then(() => { res.redirect('/'); }) .catch(err => { // 统一处理所有异步操作的错误 console.error('创建评论失败:', err); res.status(500).send('服务器内部错误'); }); };
方案二:使用async/await(推荐)
这种写法用同步风格的代码处理异步操作,可读性最高,也是现在最常用的方式:
module.exports.create = async function(req, res) { try { // 等待查询帖子的Promise完成,拿到结果 const post = await Post.findById(req.body.post); if (!post) { return res.status(404).send('目标帖子不存在'); } // 等待评论创建完成 const comment = await Comment.create({ content: req.body.content, post: req.body.post, user: req.user._id }); // 将评论添加到帖子的评论数组,然后保存帖子 post.comments.push(comment); await post.save(); // 这里一定要加await,因为save也是异步操作 // 所有操作完成后重定向 res.redirect('/'); } catch (err) { // 捕获所有异步操作中的错误,统一处理 console.error('创建评论时发生错误:', err); res.status(500).send('服务器内部错误'); } };
一些关键说明:
async关键字标记函数后,函数内部就可以使用await来等待Promise完成- 所有Mongoose的异步操作(查询、创建、保存)都要用
await等待,否则会得到未完成的Promise对象 try/catch块可以统一捕获所有异步操作的错误,避免了原来每个回调都要单独处理错误的繁琐- 原来的代码里
post.save()没有处理错误,用await后可以把它的错误也纳入catch块统一处理
备注:内容来源于stack exchange,提问作者Kashif Khan
相关产品推荐
相关产品推荐

