【问题标题】:Is it possible to skip route middleware in node express?是否可以在 node express 中跳过路由中间件?
【发布时间】:2014-07-19 12:45:17
【问题描述】:

在 express 中使用下面的 POST 函数。 (我使用的是 express 3.5.1)

app.post('/example', someFunctionOne, someFunctionTwo, function(req, res){
    if(!req.someVar){
        return res.send(400, { message: 'error'});
    } else{
        return res.json(200, { message: 'ok'}); 
    }
});

如果我从 someFunctionOne 得到一些结果,这意味着 someFunctionTwo 是多余的,有没有办法跳过 someFunctionTwo 并转到最后一个将发送响应的未命名函数?

所以我猜同样有“next()”函数,“last()”函数在哪里?如果这不可能,为什么不呢?这对我来说似乎是一个疏忽,但有充分的理由吗?

【问题讨论】:

    标签: node.js express middleware


    【解决方案1】:

    您可以执行next('route'),它将完全转到下一条路线。在这种情况下,这并不完全是您所需要的,但如果您将代码分成 2 个单独的路由,它会起作用。

    但是,我认为这种条件逻辑通常有两种方法:

    • make someFunctionOnereq 实例获得特殊结果时为其设置一些状态,并使someFunctionTwo 足够智能以检查该情况,并在找到时调用next() 并绕过自身。这是最惯用的表达方式,也是大多数中间件如何检测它们何时在同一个请求中被多次调用并避免再次重做它们的工作。
    • someFunctionOne中,当出现特殊情况时,直接调用lastFunction即可。请记住,中间件抽象不是圣杯。如果您的中间件耦合得如此紧密,也许它们应该是一个中间件和一些辅助函数。还有很多其他方式可以让您感觉更自然地组织代码。

    【讨论】:

    • 你能澄清下一个('route')是什么意思吗?你的意思是下一个('/route2')。下一条路线上似乎没有任何带有参数的文档。参数不可能是一个函数吗?我已经按照您在第一个项目符号中的建议进行了操作。当“last()”函数更简洁时,必须附加变量以跳过函数,这似乎是低效/丑陋的代码。我不能做你的第二个建议,因为所有最终函数都是命名函数(我喜欢它,因为它使函数与请求路由保持一致)
    • 不,我的意思是完全准确的next('route');。 'route' 是连接将识别的魔术字符串。
    【解决方案2】:

    我的直觉是做这样的事情:

    const funcOne = (req, res, next) => {
      // do something
      if (/* you were successful */) {
        res.locals.shouldSkipFuncTwo = true
      }
      next()
    }
    
    const funcTwo = (req, res, next) => {
      if (res.locals.shouldSkipFuncTwo) return next()
      // do whatever stuff
      next()
    }
    
    router.get('/', funcOne, funcTwo, (req, res) => {
      res.status(200).send('hello world')
    )}
    

    如果你之前没有使用过res.localshere are the express docs 就可以了。基本上,它是响应对象中的一个属性,可供您用作容器。

    【讨论】:

      【解决方案3】:

      可能最好的方法是创建一些帮助程序或将您自己的中间件而不是您的函数放入链中。

      所以您的代码将如下所示:

      app.post('/example', oneOf(key, someFunctionOne, someFunctionTwo), function(req, res){
        if(!req[key]){
          return res.send(400, { message: 'error'});
        } else{
          return res.json(200, { message: 'ok'}); 
        }
      });
      

      助手应该是这样的:

      function oneOf (key) {
        var fns = Array.prototype.slice.call(arguments, 1);
        var l = fns.length;
        return function (req, res, next) {
          var i = 0;
          function _next () {
            if (req[key] || i === l) return next();
            fns[i](req, res, _next);
            i += 1;
          }
          _next();
        }
      }
      

      如果您决定在此处执行此操作,代码将如下所示:

      app.post('/example', functionOneOrTwo, function(req, res){
        if(!req.someVar){
          return res.send(400, { message: 'error'});
        } else{
          return res.json(200, { message: 'ok'}); 
        }
      });
      
      function functionOneOrTwo(req, res, next) {
        someFunctionOne(req, res, function () {
          if (req.someVar) return next();
          someFunctionTwo(req, res, next);
        });
      }
      

      简单,但未经测试 ;-)

      【讨论】:

        【解决方案4】:

        实际上我也面临同样的问题。我刚刚找到了 express-unless 模块,它正是这样做的:https://github.com/jfromaniello/express-unless

        【讨论】:

          猜你喜欢
          • 2020-01-04
          • 2011-12-07
          • 2014-08-07
          • 2018-01-10
          • 1970-01-01
          • 2019-05-20
          • 1970-01-01
          • 1970-01-01
          • 2016-07-23
          相关资源
          最近更新 更多