繁体   English   中英

Node.js EventEmitter:如何将类上下文绑定到事件侦听器,然后移除此侦听器

[英]Node.js EventEmitter: How to bind a class context to the event listener and then remove this listener

有没有办法访问事件侦听器方法中的类上下文并可以删除侦听器?

示例 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

你可以在构造函数中执行此操作:

this.handleTestEvent = this.handleTestEvent.bind(this);
this.emitter.addListener("test", this.handleTestEvent);

如果要使用前沿,可以使用建议的绑定运算符作为快捷方式:

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);
}

我也无法删除类中的监听器。 这对我有用(参见: 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);

你可能已经解决了这个问题,但你可能已经完成了

import {EventEmitter} from "events";

class HasEvents extends EventEmitter {}

const emitter = new HasEvents();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM