You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:27:27