是否可以跳过node express中的路由中间件?

时间:2014-07-19 12:45:17

标签: node.js express middleware

在express中使用以下POST功能。 (我使用快递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()”函数?如果这不可能,为什么不呢?这似乎是对我的疏忽,但有充分的理由吗?

4 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:1)

可能是最好的方法来做一些帮助或将你自己的中间件放入链而不是你的功能。

所以你的代码看起来像是:

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);
  });
}

简单但未经测试; - )

答案 2 :(得分:1)

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

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.locals,请here are the express docs。基本上,它是响应对象中的一个属性,可供您用作容器。

答案 3 :(得分:0)

实际上我遇到了同样的问题。我刚刚找到了componentDidMount() { this._isMounted = true; window.onpopstate = ()=> { if(this._isMounted) { const { hash } = location; if(hash.indexOf('home')>-1 && this.state.value!==0) this.setState({value: 0}) if(hash.indexOf('users')>-1 && this.state.value!==1) this.setState({value: 1}) if(hash.indexOf('data')>-1 && this.state.value!==2) this.setState({value: 2}) } } } 模块,它正是这样做的:https://github.com/jfromaniello/express-unless