在写业务的时候经常需要订阅事件和取消订阅事件,通常是用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');
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.