javascript - Node.js EventEmitter: Hur man binder en klasskontext till händelselyssnaren och sedan tar bort denna lyssnare
Finns det ett sätt att få tillgång till klassens kontext i metod för händelselyssnare med möjlighet att ta bort lyssnaren?
Exempel 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);
}
}
I det här exemplet fungerar det att ta bort lyssnaren, men handleTestEvent()-metoden har ingen tillgång till klassens kontext med this. this pekar på EventEmitter-kontexten, så this.text är inte åtkomligt.
Exempel 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);
}
}
I detta exempel använder jag bind-funktionen för att binda ett klasskontext till händelselyssnaren. Nu har handleTestEvent-metoden tillgång till klasskontexten med this => this.text är åtkomligt, men lyssnaren kan inte tas bort med removeListener - det verkar som att bind skapar en ny anonym funktion, så det finns ingen referens till den bundna lyssnaren.
Exempel 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);
}
}
I det här exemplet använder jag en pilfunktion för att bevara klassens kontext i händelselyssnaren. handleTestEvent-metoden har åtkomst till klasskontexten med hjälp av this, men lyssnaren kan inte tas bort (det finns ingen referens till den bundna lyssnaren som i exempel 2).
Jag har provat ett alternativt evenemangsbibliotek - EventEmitter3 som har stöd för anpassad kontext för evenemang (klasskontext kan skickas som tredje parameter till addListener-funktionen (this.emitter.addListener("test", this.handleTestEvent, this), det fungerar perfekt, men jag vill hellre använda den medföljande EventEmitter från Node.js.
Svar #1
Du kan göra detta i konstruktorn:
this.handleTestEvent = this.handleTestEvent.bind(this);
this.emitter.addListener("test", this.handleTestEvent);
Om du vill använda den senaste tekniken kan du använda den föreslagna bindeoperatorn som en genväg:
this.handleTestEvent = ::this.handleTestEvent;
this.emitter.addListener("test", this.handleTestEvent);
Eller använd en egenskapsinitialiserare för att skapa en bunden metod:
constructor(private text: string) {
this.emitter = new EventEmitter();
this.emitter.addListener("test", this.handleTestEvent);
this.emitter.emit("test");
}
handleTestEvent = () => {
console.log(this.text);
}
