-
在写业务的时候经常需要订阅事件和取消订阅事件,通常是用
emitter.on,emitter.off来完成,如果要绑定 this 的话,会使用 emitter.on('key',this.xxx.bind(this)); 用于绑定 this -
最近看到装饰器
@expression,在想是不是可以用装饰器的方式来给某个方法自动订阅事件,但遇到了 this 指向的问题,在装饰器内无法访问到 this ,所以想请教一下各位大神应该如何实现这种想法,谢谢,下面是我的一个实现(如果不需要 this 绑定的话是可以的,但怎么可能会不要 this 绑定呢)
import EventEmitter from 'node:events';
const emitter = new EventEmitter();
const on = (eventName: string) => {
return (target: Object, methodName: string, descriptor: PropertyDescriptor) => {
// 直接这样绑定可以运行
emitter.on(eventName, descriptor.value);
const value = descriptor.value;
// 如果是这种写法,就可以有 this ,但不会执行到 get()里面,写了也没用
return {
configurable: true,
enumerable: true,
get() {
// 这里的 this 就是 Logic ,但根本不会执行到这里面
const bound = value.bind(this);
emitter.on(eventName, bound);
return bound;
}
} as PropertyDescriptor
}
}
const off = (eventName: string) => {
return (target: Object, methodName: string, descriptor: PropertyDescriptor) => {
// todo
}
}
class Logic {
value = 1;
@on('eventKey')
onStart() {
console.log('onStart');
// this 是 undefined ,我想在把 this 绑定到当前对象上,应该如何在装饰器上处理?
console.log(this); //
}
@off('start')
onDestroy() {
}
}
new Logic();
// 某些时刻会触发,这里是否模拟一下
emitter.emit('eventKey');