typescript - TypeScript:“外包”方法。干净的方式
问题描述
我目前正在研究一个我在 express 中用作中间件的类。在我进入课堂之前,请记住,稍后我将通过首先创建我的类“Authenticator”的实例然后注入它的方法来注入中间件
app.use(authInst.express)
所以关键点将是这个函数的执行上下文(this)。这是我到目前为止的代码
备选方案 1
class Authenticator {
opts:IAuthOpts ;
express: RequestHandler| ErrorRequestHandler
constructor(opts:IAuthOpts){
this.opts = opts;
this.express = function(req:Request, res:Response, next:NextFunction){
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
}
这是有效的。但是我不想在构造函数中编写函数,因为我发现它的代码非常丑陋。像这样将express方法直接放在类中
不工作
class Authenticator {
opts:IAuthOpts;
constructor(opts:IAuthOpts){
this.opts = opts;
}
express(req, res, next){
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
将不起作用,因为 express 的执行上下文会给我这个未定义的。所以剩下的就是使用这种替代方法
备选方案 2
class Authenticator {
opts:IAuthOpts ;
express: RequestHandler| ErrorRequestHandler
constructor(opts:IAuthOpts){
this.opts = opts;
this.express = _express.bind(this);
}
private _express(req, res, next){
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
现在这也有效,并且是迄今为止我对这个问题的首选解决方案,因为将方法外包给另一个文件并保持我的文件很小也很容易。缺点是绑定。我不是 bind 的忠实拥护者,因为如果我使用相同的参数调用它们,无论从哪里调用它们,我都希望我的函数返回相同的值,在这种情况下,您总是需要将类绑定到它。
是否有更好的解决方案可以从 TypeScript 类中外包一个方法,并且仍然不必使用 bind 注入执行上下文?
解决方案
您可以使用箭头函数代替绑定:
class Authenticator {
opts:IAuthOpts ;
constructor(opts:IAuthOpts){
this.opts = opts;
}
express = (req, res, next) => {
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
如果您想将实现移动到另一个文件,最清楚的方法可能是定义一个函数,该函数将, 和,Authenticator
一起作为普通参数req
,然后从箭头函数中调用该函数:res
next
class Authenticator {
opts:IAuthOpts ;
constructor(opts:IAuthOpts){
this.opts = opts;
}
express = (req, res, next) => otherFunction(this, req, res, next);
}
// In other file
function otherFunction(authenticator: Authenticator, req: Request, res: Response, next: NextFunction) {
if(authenticator.opts.enabled) {
mainController(req, res, next, authenticator.opts)
} else {
next();
}
}
如果这不是您想要的,请澄清问题。
推荐阅读
- node.js - Express Static 找不到以主题标签开头的文件
- android - 我想使用firebase数据库在webview中添加html文件我该如何添加
- c++ - 将非左值作为 const 引用参数传递。临时是在本地范围内还是在调用方范围内创建的?
- windows - 如何将长进程名称存储在 _EPROCESS
- angular - 如何在浏览器中打开文件而不是使用 ASP.NET WebApi 下载?
- html - 在 Sass 文件中创建 Mixin
- c# - 为什么这个测试需要这么长时间?
- angular - 授权过程在 Angular 5 中无法正常工作
- c# - 如何在itext7中给出一个空的新行?
- mysql - 如何在 SQL 中检索不能被 GROUPED BY 的列