如何在nodejs中调用EventEmitter的remove listener?
How to call remove listener on EventEmitter in nodejs?
我有以下代码可以在 EventEmitter
、
上添加监听器
class MyClass {
init() {
this.listener = new EventEmitter();
this.listener.on('eventName', this.onChange.bind(this));
}
onChange() {
...
}
}
如何从 EventEmitter
中删除侦听器?我可以看到两种不同的方式:
this.listener.removeListener('eventName', this.onChange)
this.listener.removeListener('eventName', this.onChange.bind(this))
我想知道我应该使用哪一个。删除时是否需要bind
?
您可以使用 bind()
或者您可以在 Node 中使用 Arrow Function。箭头函数将从调用上下文继承它们的执行上下文,这类似于 bind()
的工作方式并提供相同的功能。
this.listener.removeListener('eventName', this.onChange)
如果在 removeListener(eventName)
风格的函数中调用监听器,上述移除监听器的方法将不起作用:
const obj = new MyObject()
obj.init()
// This would blow up with a
// ReferenceError saying you cant call removeListener() on undefined
obj.listener.removeListener('event')
当您可以使用带有 class
语法的 constructor
时,不确定 init()
函数的使用。
constructor() {
this.listener = new EventEmitter()
this.boundEventNameHandler = () => this.onChange()
this.listener.on('eventName', this.boundEventNameHandler)
}
您可以使用绑定函数在使用 this
的 class 上下文中删除侦听器。
let boundEventNameHandler = this.boundEventNameHandler
this.listener.removeListener('eventName', this.boundEventNameHandler)`
此实现的示例如下所示
const EventEmitter = require('events')
class MyObject {
constructor () {
this.listener = new EventEmitter()
this.boundEventNameHandler = () => this.onChange()
this.listener.on('eventName', this.boundEventNameHandler)
}
// I would reconsider making this a property of the MyObject class
// instead, make onChange() a local function outside the MyObject
// class definition because onChange in this example is only used by the
// event listener for 'eventName'
onChange () {
console.log('event fired change')
}
removeListeners () {
let boundEventNameHandler = this.boundEventNameHandler
this.listener.removeListener('eventName', boundEventNameHandler)
}
}
对于 TypeScript / ESNext 你可以使用这个:
class MyClass {
constructor() {
this.emitter = new EventEmitter();
this.emitter.on("event1", this.listener1);
this.emitter.on("event2", this.listener2);
this.emitter.removeListener("event1", this.listener1);
this.emitter.removeListener("event2", this.listener2);
this.emitter.emit("event1"); // no output
this.emitter.emit("event2"); // no output
}
public listener1 = (e) => {
console.dir(`listener1`);
};
public listener2 = (e) => {
console.dir(`listener2`);
};
}
基本上,您定义属性并立即为它们分配绑定函数。
这样您就可以在 .on
和 .removeListener
中使用相同的函数引用。
我有以下代码可以在 EventEmitter
、
class MyClass {
init() {
this.listener = new EventEmitter();
this.listener.on('eventName', this.onChange.bind(this));
}
onChange() {
...
}
}
如何从 EventEmitter
中删除侦听器?我可以看到两种不同的方式:
this.listener.removeListener('eventName', this.onChange)
this.listener.removeListener('eventName', this.onChange.bind(this))
我想知道我应该使用哪一个。删除时是否需要bind
?
您可以使用 bind()
或者您可以在 Node 中使用 Arrow Function。箭头函数将从调用上下文继承它们的执行上下文,这类似于 bind()
的工作方式并提供相同的功能。
this.listener.removeListener('eventName', this.onChange)
如果在 removeListener(eventName)
风格的函数中调用监听器,上述移除监听器的方法将不起作用:
const obj = new MyObject()
obj.init()
// This would blow up with a
// ReferenceError saying you cant call removeListener() on undefined
obj.listener.removeListener('event')
当您可以使用带有 class
语法的 constructor
时,不确定 init()
函数的使用。
constructor() {
this.listener = new EventEmitter()
this.boundEventNameHandler = () => this.onChange()
this.listener.on('eventName', this.boundEventNameHandler)
}
您可以使用绑定函数在使用 this
的 class 上下文中删除侦听器。
let boundEventNameHandler = this.boundEventNameHandler
this.listener.removeListener('eventName', this.boundEventNameHandler)`
此实现的示例如下所示
const EventEmitter = require('events')
class MyObject {
constructor () {
this.listener = new EventEmitter()
this.boundEventNameHandler = () => this.onChange()
this.listener.on('eventName', this.boundEventNameHandler)
}
// I would reconsider making this a property of the MyObject class
// instead, make onChange() a local function outside the MyObject
// class definition because onChange in this example is only used by the
// event listener for 'eventName'
onChange () {
console.log('event fired change')
}
removeListeners () {
let boundEventNameHandler = this.boundEventNameHandler
this.listener.removeListener('eventName', boundEventNameHandler)
}
}
对于 TypeScript / ESNext 你可以使用这个:
class MyClass {
constructor() {
this.emitter = new EventEmitter();
this.emitter.on("event1", this.listener1);
this.emitter.on("event2", this.listener2);
this.emitter.removeListener("event1", this.listener1);
this.emitter.removeListener("event2", this.listener2);
this.emitter.emit("event1"); // no output
this.emitter.emit("event2"); // no output
}
public listener1 = (e) => {
console.dir(`listener1`);
};
public listener2 = (e) => {
console.dir(`listener2`);
};
}
基本上,您定义属性并立即为它们分配绑定函数。
这样您就可以在 .on
和 .removeListener
中使用相同的函数引用。