Is there a way to access the class context in the event listener method with the ability to remove the listener?
Example 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); } }
In this example, removing the listener works, but the handleTestEvent() method does not have access to the class context using this . this points to an EventEmitter context, so this.text not available.
Example 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); } }
In this example, I use the bind function to bind the class context to an event listener. Now the handleTestEvent method has access to the class context using this => this.text , but the listener cannot be removed using removeListener - it seems that bind creates a new anonymous function, so there is no link to the limited listener.
Example 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", this.handleTestEvent); } private handleTestEvent() { console.log(this.text); } }
In this example, I use the arrow function to save the context of the class in an event listener. handleTestEvent has access to the class context using this , but the listener cannot be deleted (there is no reference to the restricted listener, as in example 2).
I tried an alternative event library - EventEmitter3 , which supports a custom context for events (the class context can be passed as the third parameter to the addListener function ( this.emitter.addListener("test", this.handleTestEvent, this ), it works fine, but I prefer to use included EventEmitter from Node.js.