Node.js 返回后继续执行nodejs中间件

Node.js 返回后继续执行nodejs中间件,node.js,middleware,Node.js,Middleware,我有以下中间件: const mongoose = require('mongoose'); module.exports = function(req, res, next) { const keys = Object.keys(req.params); keys.forEach(elem => { if ( (elem.includes('id') || elem.includes('Id')) && !mongoose.Typ

我有以下中间件:

const mongoose = require('mongoose');

module.exports = function(req, res, next) {
  const keys = Object.keys(req.params);
  keys.forEach(elem => {
    if (
      (elem.includes('id') || elem.includes('Id')) &&
      !mongoose.Types.ObjectId.isValid(req.params[elem])
    )
      return res
        .status(400)
        .json({ msg: `id: ${req.params[elem]} is invalid` });
  });
  next();
};
module.exports = function(req, res, next) {
  const keys = Object.keys(req.params);
  keys.forEach(elem => {
    if (
      (elem.includes('id') || elem.includes('Id')) &&
      !mongoose.Types.ObjectId.isValid(req.params[elem])
    ) {
      // === Report the error and let the router handle it
      return next({
        type: "invalidinput",
        msg: `id: ${req.params[elem]} is invalid`
      );  
    }
  });
  next();
};
在get请求中调用它:

// @route   GET api/movies/:id
// @desc    Get a movie with specified id from db
// @access  Public
router.get('/:id', checkId, async (req, res) => {
const movie = await Movie.findById(req.params.id);
res.json(movie);
});
当我在邮递员中使用无效id(例如:1234)发出请求时,我收到了正确的响应400,消息为:“ID1234无效”,但执行仍然传递到reqest回调代码,并且在我尝试使用无效id访问db时抛出错误


所以问题是,为什么中间件仍然允许执行next(),即使它已经随400一起返回?

您需要通过调用
next(“某些错误”)
告诉路由器出现了问题。例如,您可以这样做:

module.exports = function(req, res, next) {
  const keys = Object.keys(req.params);
  keys.forEach(elem => {
    if (
      (elem.includes('id') || elem.includes('Id')) &&
      !mongoose.Types.ObjectId.isValid(req.params[elem])
    ) {
      res
        .status(400)
        .json({ msg: `id: ${req.params[elem]} is invalid` });
      return next("invalidinput");
    }
  });
  next();
};
或者,如果您愿意,您可以通过在路由器外部设置结果来实现更通用的功能,如下所示:

在您的中间件中:

const mongoose = require('mongoose');

module.exports = function(req, res, next) {
  const keys = Object.keys(req.params);
  keys.forEach(elem => {
    if (
      (elem.includes('id') || elem.includes('Id')) &&
      !mongoose.Types.ObjectId.isValid(req.params[elem])
    )
      return res
        .status(400)
        .json({ msg: `id: ${req.params[elem]} is invalid` });
  });
  next();
};
module.exports = function(req, res, next) {
  const keys = Object.keys(req.params);
  keys.forEach(elem => {
    if (
      (elem.includes('id') || elem.includes('Id')) &&
      !mongoose.Types.ObjectId.isValid(req.params[elem])
    ) {
      // === Report the error and let the router handle it
      return next({
        type: "invalidinput",
        msg: `id: ${req.params[elem]} is invalid`
      );  
    }
  });
  next();
};
然后在路由器的底部:

// handle any errors
router.use(err, req, res, next) => {
  if (err) {
    if (err.type === "invalidinput") {
      return req.status(400).json({msg: err.msg});
    }
    else {
      return res.status(500).json({msg: "Internal error."});
    }
  }
  return next();
}

这里另一个可能的解决方案是将forEach转换为经典的for循环,从而使该中间件同步运行

module.exports = function(req, res, next) {
  const keys = Object.keys(req.params);
  for (let i = 0; i < keys.length; i++) {
    if (
      (keys[i].includes('id') || keys[i].includes('Id')) &&
      !mongoose.Types.ObjectId.isValid(req.params[keys[i]])
    )
      return res
        .status(400)
        .json({ msg: `id: ${req.params[keys[i]]} is invalid` });
  }
  next();
};
module.exports=功能(req、res、next){
常量键=对象键(请求参数);
for(设i=0;i
这是否回答了您的问题?您正在循环中返回http响应!最好写一个承诺并在无效时拒绝,然后处理这个承诺。