如何用async/await改写NodeJS中CRUD回调式控制器代码
使用async/await改写Mongoose CRUD控制器
核心改写思路
- 将每个控制器函数声明为
async function,获得使用await的权限 - 用
await替代.then()链式调用,直接获取异步操作的返回结果 - 用
try/catch块统一捕获异步错误,替代.catch()回调逻辑
改写后的完整代码
// 创建课程 export async function createCourse(req, res) { try { const course = new Course({ _id: mongoose.Types.ObjectId(), title: req.body.title, description: req.body.description, }); const newCourse = await course.save(); return res.status(201).json({ success: true, message: 'New course created successfully', Course: newCourse, }); } catch (error) { console.log(error); return res.status(500).json({ success: false, message: 'Server error. Please try again.', error: error.message, }); } } // 获取所有课程 export async function getAllCourse(req, res) { try { const allCourse = await Course.find().select('_id title description'); return res.status(200).json({ success: true, message: 'A list of all course', Course: allCourse, }); } catch (err) { return res.status(500).json({ success: false, message: 'Server error. Please try again.', error: err.message, }); } } // 获取单个课程 export async function getSingleCourse(req, res) { try { const id = req.params.courseId; const singleCourse = await Course.findById(id); // 优化:未找到课程时返回404,更符合HTTP语义 if (!singleCourse) { return res.status(404).json({ success: false, message: 'This course does not exist', }); } return res.status(200).json({ success: true, message: `More on ${singleCourse.title}`, Course: singleCourse, }); } catch (err) { return res.status(500).json({ success: false, message: 'Server error. Please try again.', error: err.message, }); } } // 更新课程 export async function updateCourse(req, res) { try { const id = req.params.courseId; const updateObject = req.body; // 推荐用findByIdAndUpdate替代已过时的update方法,{new: true}返回更新后的文档 const updatedCourse = await Course.findByIdAndUpdate(id, {$set: updateObject}, {new: true}); if (!updatedCourse) { return res.status(404).json({ success: false, message: 'This course does not exist', }); } return res.status(200).json({ success: true, message: 'Course is updated', updateCourse: updatedCourse, // 返回实际更新后的文档更准确 }); } catch (err) { return res.status(500).json({ success: false, message: 'Server error. Please try again.', error: err.message, }); } } // 删除课程 export async function deleteCourse(req, res) { try { const id = req.params.courseId; const deletedCourse = await Course.findByIdAndRemove(id); if (!deletedCourse) { return res.status(404).json({ success: false, message: 'This course does not exist', }); } return res.status(204).json({ success: true, }); } catch (err) { return res.status(500).json({ success: false, message: 'Server error. Please try again.', error: err.message, }); } }
额外优化建议
- 统一错误处理:抽离全局错误处理中间件,避免重复编写
try/catch:
控制器中只需抛出错误,由中间件统一处理:// 全局错误处理中间件 export function errorHandler(err, req, res, next) { console.error(err.stack); res.status(500).json({ success: false, message: 'Server error. Please try again.', error: err.message, }); }export async function createCourse(req, res, next) { try { // ...业务逻辑 } catch (err) { next(err); } } - 请求参数验证:用
express-validator或Joi验证req.body和req.params,提前拦截非法请求 - REST规范对齐:资源不存在时返回
404,而非统一500,更贴合HTTP设计语义
内容的提问来源于stack exchange,提问作者kato
相关产品推荐
相关产品推荐

