我希望始终执行expressjs middlware。 即使next()中存在错误,也就是说。
有可能吗?
示例
app.get('/',[middle1,middle2],doIt)
即使middle1执行next而出错,mid2也应该始终执行。
注意:middle2应始终执行last并获取先前中间件计算的值。在middle1和middle2之间也有很多中间件。
答案 0 :(得分:1)
如果已知middle1
不使用它调用next()的任何异步操作,那么你可以将其包装并在其周围放置一个try / catch,这样如果它抛出,你只需调用{{ 1}}代表它。
如果它确实使用了异步操作,或者您不知道它是否会使用异步操作,那么只有在它同步抛出(在异步之前)并且您将无法捕获任何操作时,您将只捕获它的异常它异步抛出的异常。关于异步行为可以做的最好的事情是在包装器中设置某种超时。如果它在某段时间内没有调用next()
(因为它抛出异常或者其他一些异常失败),那么你会在超时期限之后调用next。
包装非异步next()
可能如下所示:
middle1
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);
函数将stub作为中间件函数插入。该stud插入自己的wrap()
函数,以便它可以判断实际的中间件函数是否调用next()
。然后它围绕中间件函数包装一个异常处理程序,因此如果它同步抛出异常,那么它就可以恢复。函数返回后,它会检查是否调用next()
,如果没有,则调用它。
如前所述,只有中间件功能是同步的,这种方法才有效。
答案 1 :(得分:0)
假设你不关心执行的顺序,你可以简单地在app.use中执行函数middle2。
app.use(middle2);
app.get('/pathx, middle1, middle3, doIt);
mid2将始终在每个请求上执行。但是,middle2将在任何其他中间件之前执行
如果你需要mid2按顺序执行最后一次,那么使用异步模块进行简单修改就可以完成你想要的任务
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);