如何用另一个函数包装每个快速路由处理程序

时间:2016-06-09 17:58:44

标签: javascript node.js function express apply

基本上我想要而不是这个...

app.get(routes.test, function(req, res, next){
  actualRouteHandler(req, res, next) // Always returns a promise or throws.
    .catch(function(err) {
      next(err);
    });
});

有这个: app.get(routes.test, catchWrap(actualRouteHandler));

或者类似的东西,我已经尝试过使用fn.apply和东西,但我找不到一种方法来传递actualRouteHandler正确的参数(req,res,next)并且仍然具有该功能。我需要返回一个函数或类似的东西吗?

编辑:我认为可能有库可以执行此操作,但我们无法访问此代码中的实际快速应用程序。

2 个答案:

答案 0 :(得分:6)

在您的具体情况下,catchWrap将如下所示:

function catchWrap(originalFunction) {
    return function(req, res, next) {
        try {
            return originalFunction.call(this, req, res, next);
        } catch (e) {
            next(e);
        }
    };
}

返回一个新函数,当调用它时,将使用你的catch包装器调用原始函数。关键部分是它创建并返回一个函数(return function(req, res, next) { ... };)和这一行:

return originalFunction.call(this, req, res, next);

Function#call调用给定的函数,说明在调用期间使用this的内容(在上面我们传递了我们收到的this)以及在调用中使用的参数。

你在展示时使用它:

app.get(routes.test, catchWrap(actualRouteHandler));

或者如果您更喜欢将实际处理程序定义为匿名函数:

app.get(routes.test, catchWrap(function(req, res, next) {
    // ...handler code here...
}));

catchWrap特定于您的情况,因为如果抛出异常,您希望调用next(e)。 “将此函数包装在另一个函数中”的泛型形式如下:

function catchWrap(originalFunction) {
    return function() {
        try {
            // You can do stuff here before calling the original...
            // Now we call the original:
            var retVal = originalFunction.apply(this, arguments);
            // You can do stuff here after calling the original...
            // And we're done
            return retVal;
        } catch (e) {
            // you can do something here if you like, then:
            throw e; // Or, of course, handle it
        }
    };
}

arguments是JavaScript提供的伪数组,包含调用当前函数的所有参数。 Function#apply就像Function#call一样,除了你将参数用作数组(或伪数组)而不是离散。

答案 1 :(得分:0)

以下简单方法可用于设置通用错误处理程序 -

步骤1:在注册路由后编写错误处理程序。因此,例如,如果您要注册多条路线,请执行以下操作:

config.getGlobbedFiles('./app/routes/modules/**/*.js').forEach(function (routePath) {
        require(path.resolve(routePath))(app);
    });

注册路线后,您可以设置一般错误处理程序 -

app.use(function (err, req, res, next) {

        // If the error object doesn't exists
        if (err != undefined) {
            //do error handling
        }
        else {
            //no error found
        }

    }); 

步骤2:在路由处理程序中,如果未找到错误,则需要确保调用“next()”。如果出现错误,您需要调用“next(err)”。