Javascript 如何用另一个函数包装每个express route处理程序
基本上我想代替这个Javascript 如何用另一个函数包装每个express route处理程序,javascript,node.js,function,express,apply,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)) 或者类似
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)并且仍然具有该函数。我是否需要返回函数或类似的东西
编辑:我认为可能有库可以做到这一点,但在这段代码中,我们无法访问实际的express应用程序。以下简单方法可用于设置通用错误处理程序-
app.use(function (err, req, res, next) {
// If the error object doesn't exists
if (err != undefined) {
//do error handling
}
else {
//no error found
}
});
步骤1:注册路由后编写错误处理程序。因此,例如,如果您正在像这样注册多条路由:
config.getGlobbedFiles('./app/routes/modules/**/*.js').forEach(function (routePath) {
require(path.resolve(routePath))(app);
});
function catchWrap(originalFunction) {
return function(req, res, next) {
try {
return originalFunction.call(this, req, res, next);
} catch (e) {
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
}
};
}
注册路由后,可以设置通用错误处理程序-
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()”。如果出现错误,您需要调用“下一步(错误)”。在您的特定情况下,catchWrap
如下所示:
config.getGlobbedFiles('./app/routes/modules/**/*.js').forEach(function (routePath) {
require(path.resolve(routePath))(app);
});
function catchWrap(originalFunction) {
return function(req, res, next) {
try {
return originalFunction.call(this, req, res, next);
} catch (e) {
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
}
};
}
这将返回一个新函数,当调用该函数时,该函数将调用包含catch包装的原始函数。关键部分是它创建并返回一个函数(返回函数(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)
,如果抛出,则会出现异常。“将此函数包装到另一个函数中”的一般形式如下:
config.getGlobbedFiles('./app/routes/modules/**/*.js').forEach(function (routePath) {
require(path.resolve(routePath))(app);
});
function catchWrap(originalFunction) {
return function(req, res, next) {
try {
return originalFunction.call(this, req, res, next);
} catch (e) {
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
类似,只是您给出了用作数组(或伪数组)而不是离散数组的参数。我觉得app.use是用于中间件的,我基本上只想将我的控制器的每个处理程序包装在一个小函数中,然后将捕获到的任何异常传递给我的实际错误处理中间件。例如,我问如何使用事件处理程序执行此操作,您知道如何执行吗?例如,el.addEventListener('click',handleFunction)
但将handleFunction包装在另一个函数中,该函数表示。。。在其他函数周围添加try/catch块,或添加其他一些功能。它不必与express相关,我只是不知道如何以这种方式传递函数和其他参数。不,我们可以随意添加中间件和路由,但不能说。。。使用Express Promise Router(),因为我们无法访问实际的Express应用程序,我们只能在它的基础上进行构建,这远远不够理想。哦,酷,我可以回答这个问题!:-)令人惊奇的是,就是这样的时刻,你真的很想知道为什么你自己没有想到这些事情,你把事情做得很简单,干杯。我唯一要问的是传递这个
,这是否意味着当我在原始函数
中引用这个时,它将使用外部函数中的这个
?如果我不需要使用this
,我可以正常调用该函数吗?按照上面写的方式,它将使用调用包装时使用的this
(匿名函数catchWrap
返回)。因此,如果Express使用了一个特定的这个,我们将其传递;如果Express只是调用函数,而不做任何设置this
,this
将是全局对象(在松散模式下)或未定义的对象(在严格模式下),我们再次传递它。因此,originalFunction.call(this,…)
的一般模式通常是最好的。但是如果您知道originalFunction
不需要任何特定的this
,是的,您可以直接调用它。