总是在expressjs中运行一个中间件

我想要一个expressjs middlware总是被执行。 即使next()中有错误也是如此。

可能吗?

app.get('/',[middle1,middle2],doIt) 

即使middle1执行下一个错误,middle2也应该始终执行。

注意:middle2应该总是执行最后一个,并采用之前中间件计算的值。 middle1和middle2之间也有很多中间件。

如果middle1已知不使用next()调用的任何asynchronous操作,那么可以将它包装起来,并围绕它放置一个try / catch,如果它抛出,可以代表它调用next()

如果它使用asynchronous操作,或者你不知道它是否会使用asynchronous操作,那么你将只捕获它的exception,如果它同步抛出(asynchronous之前),你将无法捕捉asynchronous抛出exception。 关于asynchronous行为的最佳做法是在包装器中设置某种超时。 如果它在一段时间内没有调用next() ,或者因为抛出了一个exception,或者只是在其他一些错误的时候失败了,那么在超时期限之后再调用next()。

包装非asynchronousmiddle1可能如下所示:

 function wrap(fn) { return function(req, res, next) { var nextCalled = false; try { fn(req, res, function() { nextCalled = true; next(); }); } finally { if (!nextCalled) { next(); } } } } app.get('/',[wrap(middle1),middle2],doIt); 

wrap()函数插入一个存根作为中间件函数。 该柱头插入自己的next()函数,以便能够确定实际的中间件函数是否调用next() 。 然后它围绕中间件函数包装一个exception处理程序,所以如果它同步抛出一个exception,那么它可以恢复。 函数返回后,它检查next()被调用,如果没有,它调用它。

如前所述,只有中间件function是同步的,这种方法才有效。

假设你不关心执行的顺序,你可以简单的在app.use里面执行函数middle2。

 app.use(middle2); app.get('/pathx, middle1, middle3, doIt); 

middle2将始终在每个请求上执行。 但是,middle2会在任何其他中间件之前执行

如果你需要middle2顺序执行最后一个,那么使用asynchronous模块进行一个简单的修改就可以完成你想要的任务

 async = require('async'); function middleware(req, res, next){ var functionList = [middle1, middle3]; async.series(functionList, function(err, results){ if(err){ middle2(req, res, next); next(err); } middle2(req, res, next); next(); } } app.get('/pathX', middleware, doIt);