Узел.JS EventEmitter: как привязать контекст класса к прослушивателю событий, а затем удалить этот прослушиватель
есть ли способ доступа к контексту класса в методе прослушивателя событий с возможностью удаления прослушивателя?
Пример 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()
метод не имеет доступа к контексту класса с помощью this
. this
указывает на контекст 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", this.handleTestEvent);
}
private handleTestEvent() {
console.log(this.text);
}
}
в этом примере я использую функцию стрелки сохраните контекст класса в прослушивателе событий. handleTestEvent
метод имеет доступ к контексту класса с помощью this
, но слушатель не может быть удален (нет ссылки на ограниченный слушатель, как в Примере 2).
я пробовал альтернативную библиотеку событие - EventEmitter3 который поддерживает пользовательский контекст для событий (контекст класса может быть передан в качестве третьего параметра в
2 ответов
вы можете сделать это в конструкторе:
this.handleTestEvent = this.handleTestEvent.bind(this);
this.emitter.addListener("test", this.handleTestEvent);
Если вы хотите использовать передний край, вы можете использовать предлагаемый оператор bind как ярлык:
this.handleTestEvent = ::this.handleTestEvent;
this.emitter.addListener("test", this.handleTestEvent);
или использовать собственность инициализатора чтобы создать связанный метод:
constructor(private text: string) {
this.emitter = new EventEmitter();
this.emitter.addListener("test", this.handleTestEvent);
this.emitter.emit("test");
}
handleTestEvent = () => {
console.log(this.text);
}
вы, вероятно, разобрались в этом, но вы могли бы просто сделать
import {EventEmitter} from "events";
class HasEvents extends EventEmitter {}
const emitter = new HasEvents();