有没有办法在事件监听器方法中访问类上下文,并有可能删除监听器?
示例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,它支持事件的自定义上下文(类上下文可以作为第三个参数传递给addListener
函数(this.emitter.addListener("test", this.handleTestEvent, this
) ,它工作得很好,但我宁愿使用Node.js中包含的EventEmitter。
答案 0 :(得分:7)
您可以在构造函数中执行此操作:
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);
}
答案 1 :(得分:0)
我也无法删除课程中的侦听器。这对我有用(请参阅:https://nodejs.org/api/events.html#events_emitter_rawlisteners_eventname)
emitter.on('error', this.onError.bind(this));
this.onErrorListener = emitter.rawListeners('error').splice(-1)[0];
...
emitter.off('error', this.onErrorListener);
答案 2 :(得分:-1)
你可能已经对此进行了整理,但你可能已经完成了
import {EventEmitter} from "events";
class HasEvents extends EventEmitter {}
const emitter = new HasEvents();