2017-03-17 88 views
0

我试图使用一个中间件数组。好吧,更像是函数名和数组的组合。在express.js上使用一组中间件

而是具有:

router.post('/editPassword', validate, changePassword, sendConfirmation); 

我想有这样的:

router.post('/editPassword', validate, [changePassword, sendConfirmation]); 

这将是这样的:

router.post('/editPassword', validate, doAction); 

doAction会是这样的一个数组:

var doAction = [ 
    //equivalent of changePassword 
    function(req, res, next){ 
     //whatever 
     next(); 
    }, 

    //equivalent to the previous sendConfirmation 
    function(req, res, next){ 
     //whatever 
    } 
] 

但它似乎失败了,并且在doAction的第一个函数内返回next()之后的validate步骤。

我正在寻找一种方法来简化中间件链接,其中包括一些中间件步骤同名。

+0

你有没有尝试把'验证'在数组以及仅用于测试目的? – Tholle

+1

你能解释一下_“回到'validate'步骤”吗?它是否再次调用该中间件? – robertklep

+0

对不起,我的错。它似乎工作得很好。 我在'next()'之后忘了return语句。所以...现在我想知道,为什么使用组合中间件,那么如果这工作得很好? – Alvaro

回答

1

我假设你希望它看起来这样的原因不仅是因为它看起来很像,而且能够重用其他中间件。在这种情况下,您可以创建一个运行所有其他中间件的中间件来为您进行检查,并且只有在所有验证成功时才调用下一个函数。

var express = require('express'); 
var app = express(); 

function middleware1(req, res, next) { 
    if(req.query.num >= 1) { 
     next(); 
    } else { 
     res.json({message: "failed validation 1"}); 
    } 
} 

function middleware2(req, res, next) { 
    if(req.query.num >= 2) { 
     next(); 
    } else { 
     res.json({message: "failed validation 2"}); 
    } 
} 

function middleware3(req, res, next) { 
    if(req.query.num >= 3) { 
     next(); 
    } else { 
     res.json({message: "failed validation 3"}); 
    } 
} 

function combination(req, res, next) { 
    middleware1(req, res, function() { 
     middleware2(req, res, function() { 
      middleware3(req, res, function() { 
       next(); 
      }) 
     }) 
    }) 
} 


app.get('/', combination, function (req, res) { 
    res.send('Passed All Validation!'); 
}) 

app.listen(3000, function() { 
    console.log('Example app listening on port 3000!') 
}) 

可以通过运行它,然后观看http://localhost:3000/?num=3,改变值3到较低的数目,或除去num参数测试此应用。

我不确定这是否是正确的方法,但这是我处理其他项目的方式。让我知道你的想法。

note:请参阅用例注释。这取决于你想如何使用中间件

+0

'combination'基本上做了当Express在路由处理程序中传递多个中间件函数(在一个数组中)时内部已经做了什么。所以它与app.get(...,middleware1,middleware2,middleware3)类似。 – robertklep

+0

@robertklep是的,但是如果您有多条使用该序列并决定稍后更改组合模式的路由,则可以在组合中间件中执行此操作,而不是查找和更改使用它的每条路由。 – Brian

+1

在这种情况下,执行此操作:'let combination = [middleware1,middleware2,middleware3]',并且只使用'combination'而不是分别传递这三个函数。 – robertklep

1

只要搜索多一点^^ @robertklep可以有一个更好的解决方案:少丑,比以前的答案更容易理解

https://github.com/blakeembrey/compose-middleware

+0

只是注意到这是我身边的一个错误。所以...现在我想知道,为什么使用'compose-middleware',那么如果这工作得很好?有什么优势? – Alvaro

+0

好处是可以轻松组合中间件以供重用(例如,在expressjs项目中:您使用2个中间件,同时拥有另一个中间件,对另一个项目也有用)。如果中间件2出现故障,并且只有中间件2成功时才调用中间件3,那么您也可以使用下一个控件来调用) – jy95

1

要小心,你不这样做(相当于)这个在你validate中间件:

function middleware(req, res, next) { 
    if (someCondition) { 
    console.log('some condition is true'); 
    next(); 
    } 
    console.log('some condition is false'); 
    res.status(400).end(); 
} 

这样做的目的是,呼吁next后不执行代码的其余部分,BU它会。 next没什么特别的,所以当你调用它时,在它返回后中间件代码继续运行(导致“某些条件成立”“某些条件为假”被记录)。

这就是为什么你经常会看到这样:

if (someCondition) { 
    console.log('some condition is true'); 
    return next(); 
    // Or, alternatively: 
    // next(); 
    // return; 
    } 

return导致中间件函数调用next后返回,所以在函数的代码的其余部分将不会被执行。

相关问题