Node.js 始终在expressjs中运行中间件

Node.js 始终在expressjs中运行中间件,node.js,express,Node.js,Express,我希望始终执行expressjs middlware。 即使next()中是否存在错误,也是如此 可能吗 范例 app.get('/',[middle1,middle2],doIt) 即使middle1下一步执行时出错,middle2也应始终执行 注意:middle2应始终在最后执行,并采用以前的中间件计算的值。此外,在middle1和middle2之间还有很多中间软件。如果已知middle1不使用任何异步操作来调用next(),那么您可以对其进行包装,并在其周围放置try/catch,这样,

我希望始终执行expressjs middlware。 即使next()中是否存在错误,也是如此

可能吗

范例

app.get('/',[middle1,middle2],doIt)
即使middle1下一步执行时出错,middle2也应始终执行


注意:middle2应始终在最后执行,并采用以前的中间件计算的值。此外,在middle1和middle2之间还有很多中间软件。

如果已知
middle1
不使用任何异步操作来调用next(),那么您可以对其进行包装,并在其周围放置try/catch,这样,如果它抛出,您就可以代表它调用
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);
wrap()
函数插入一个存根作为中间件函数。该螺柱插入自己的
next()
函数,这样它就可以判断实际的中间件函数是否调用
next()
。然后,它将异常处理程序包装在中间件函数周围,这样,如果它同步抛出异常,那么它就可以恢复。函数返回后,检查是否调用了
next()
,如果没有,则调用它


如前所述,只有在中间件功能是同步的情况下,此方法才有效。

假设您不关心执行顺序,您只需让函数middle2在app.use内执行即可

app.use(middle2);

app.get('/pathx, middle1, middle3, doIt);
middle2将始终在每次请求时执行。但是,middle2将在任何其他中间件之前执行

如果您要求middle2按顺序最后执行,那么使用异步模块进行简单的修改应该可以实现您想要的功能

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

在middle1之后安排middle2函数,感谢您的想法,您可以实现这一点,但是我有两个以上的中间件异步函数。即使它在下一个中间件中抛出错误,我需要始终执行最后一个中间件,不,我无法将此中间件移动到第一个中间件,因为我正在使用最后一个中间件中其他中间件的结果。我认为处理此问题的唯一方法是不在下一个中间件中抛出错误,而是在side req对象中的变量中抛出错误。?@NisanthSojan-这是您自己的吗中间件?如果是这样,就让它不抛出或捕获自己的异常。如果不是,为什么要扔?如果它在扔东西,你一定是出了什么问题。如果您不想中止请求,那么加入中间件基本上是不好的。应该通过使中间件防弹以防抛出,或者通过预飞中间件抛出的任何东西来避免它,如果它只是要抛出,则避免中间件。通过抛出,我的意思是执行next(),并将error作为第一个参数。哦,对不起,我的错:)@NisanthSojan-那么请解决你的问题,因为到目前为止,所有写的东西都假设“抛出”意味着“抛出异常”,这几乎是每个人都会解释你所写内容的方式。