有没有办法在事件监听器方法中访问类上下文,并有可能删除监听器?
例1:
import {EventEmitter} from "events"; export default class EventsExample1 { private emitter: EventEmitter; constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test",this.handleTestEvent); this.emitter.emit("test"); } public dispose() { this.emitter.removeListener("test",this.handleTestEvent); } private handleTestEvent() { console.log(this.text); } }
在此示例中,删除侦听器是可行的,但handleTestEvent()方法无法使用此方法访问类上下文.这指向EventEmitter上下文,因此无法访问this.text.
例2:
import {EventEmitter} from "events"; export default class EventsExample2 { private emitter: EventEmitter; constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test",this.handleTestEvent.bind(this)); this.emitter.emit("test"); } public dispose() { this.emitter.removeListener("test",this.handleTestEvent); } private handleTestEvent() { console.log(this.text); } }
在这个例子中,我使用bind
函数将类的上下文绑定到事件侦听器.现在,handleTestEvent方法可以使用this =>访问类上下文. this.text是可访问的,但是无法使用removeListener
删除侦听器 – 似乎bind创建了一个新的匿名函数,因此没有对有界侦听器的引用.
例3:
import {EventEmitter} from "events"; export default class EventsExample3 { private emitter: EventEmitter; constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test",() => this.handleTestEvent()); this.emitter.emit("test"); } public dispose() { this.emitter.removeListener("test",我使用箭头函数来保留事件监听器中的类的上下文. handleTestEvent方法可以使用它来访问类上下文,但是无法删除侦听器(没有像示例2那样引用有界侦听器).我已经尝试了另一个事件库 – EventEmitter3,它支持事件的自定义上下文(类上下文可以作为第三个参数传递给addListener函数(this.emitter.addListener(“test”,this.handleTestEvent,this),它工作得很好,但我宁愿使用Node.js中包含的EventEmitter.
解决方法
你可以在构造函数中执行此操作:
this.handleTestEvent = this.handleTestEvent.bind(this); this.emitter.addListener("test",this.handleTestEvent);
如果要使用前沿,可以使用proposed bind operator作为快捷方式:
this.handleTestEvent = ::this.handleTestEvent; this.emitter.addListener("test",this.handleTestEvent);
或使用property initializer创建绑定方法:
constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test",this.handleTestEvent); this.emitter.emit("test"); } handleTestEvent = () => { console.log(this.text); }