javascript - Node.js 事件发射器 : How to bind a class context to the event listener and then remove this listener

标签 javascript node.js events typescript 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函数将类的上下文绑定(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);

如果你想使用切削刃,你可以使用proposed bind operator作为快捷方式:

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

或者使用 property initializer创建绑定(bind)方法:

constructor(private text: string) {
  this.emitter = new EventEmitter();

  this.emitter.addListener("test", this.handleTestEvent);
  this.emitter.emit("test");
}

handleTestEvent = () => {
  console.log(this.text);
}

关于javascript - Node.js 事件发射器 : How to bind a class context to the event listener and then remove this listener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39820651/

相关文章:

javascript - 允许用户通过URL上传图片时需要注意什么?

javascript - 更改 Javascript/Jquery 中的 JSON 结构

javascript - 是否可以调用第二层原型(prototype)函数?

javascript - 为什么我不能在屏幕上或使用 Forever 运行 node.js 和 socket.io?

javascript - 基于当前所选选项卡的动态导航栏突出显示

javascript - 如何从 node.js 脚本中的 CDN 链接导入 JavaScript 库

node.js - nodejs child_process.spawn msdeploy.exe,目标站点中有空格

api - 如何修改 Google 日历的颜色定义以允许自定义事件颜色?

javascript - 防止复选框在单击时取消选中(不禁用或只读)

java - 为 Java 代码添加十进制毫秒延迟