打字稿:"Outsourcing" 方法。干净的方式
TypeScript: "Outsourcing" methods. The clean way
我目前正在开发 class 我在 express 中用作中间件。在我进入 class 之前,请记住我稍后将通过首先创建我的 Class "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 中,像这样
不工作
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 的忠实粉丝,因为我希望我的函数 return 相同的值,如果我用相同的参数调用它们,无论它们是从哪里调用的,在这种情况下,你总是需要绑定 class 到它。
是否有更好的解决方案来从 TypeScript 外包方法 class 并且仍然不必使用 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
、[=14= 的函数可能是最清楚的], 和 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();
}
}
如果这不是您要查找的内容,请澄清问题。
我目前正在开发 class 我在 express 中用作中间件。在我进入 class 之前,请记住我稍后将通过首先创建我的 Class "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 中,像这样
不工作
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 的忠实粉丝,因为我希望我的函数 return 相同的值,如果我用相同的参数调用它们,无论它们是从哪里调用的,在这种情况下,你总是需要绑定 class 到它。
是否有更好的解决方案来从 TypeScript 外包方法 class 并且仍然不必使用 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
、[=14= 的函数可能是最清楚的], 和 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();
}
}
如果这不是您要查找的内容,请澄清问题。