【发布时间】:2020-09-21 14:27:00
【问题描述】:
以下是我用来创建自定义事件发射器的代码。
这样所有继承 EventEmitter 类的类都可以发出和监听事件。 目前事件发射只发生在一个方向。
即。从孩子到父母。
(假设child和parent都继承自EventEmitter类)
class EventEmitter {
listeners = {}
addListener(eventName, fn) {
this.listeners[eventName] = this.listeners[eventName] || [];
this.listeners[eventName].push(fn);
return this;
}
on(eventName, fn) {
return this.addListener(eventName, fn);
}
once(eventName, fn) {
this.listeners[eventName] = this.listeners[eventName] || [];
const onceWrapper = () => {
fn();
this.off(eventName, onceWrapper);
}
this.listeners[eventName].push(onceWrapper);
return this;
}
off(eventName, fn) {
return this.removeListener(eventName, fn);
}
removeListener (eventName, fn) {
let lis = this.listeners[eventName];
if (!lis) return this;
for(let i = lis.length; i > 0; i--) {
if (lis[i] === fn) {
lis.splice(i,1);
break;
}
}
return this;
}
emit(eventName, ...args) {
let fns = this.listeners[eventName];
if (!fns) return false;
fns.forEach((f) => {
f(...args);
});
return true;
}
listenerCount(eventName) {
let fns = this.listeners[eventName] || [];
return fns.length;
}
rawListeners(eventName) {
return this.listeners[eventName];
}
}
所以我的要求是我想在这个 EventEmitter 类中创建一个名为 triggerChild(eventName) 的新方法,这样当我在父类的子实例上触发此事件时,在子类内部设置一个监听器eventName 将自动被触发并运行一些逻辑。
有点像这样
/// parent class
class Parent extends EventEmitter{
constructor() {
this.childinstance = new Child()
this.parentmethod()
}
parentmethod() {
this.childinstance.triggerChild(eventName)
}
}
&在子实例中
/// child instance class
class Child extends EventEmitter{
constructor () {
this.on(eventName, () => do some logic)
}
}
我本可以这样做:
/// parent class
class Parent extends EventEmitter{
constructor() {
this.childinstance = new Child()
this.parentmethod()
}
parentmethod() {
this.childinstance.runAnyChildMethod()
}
}
但这不是我想要的。我想用 EventEmitter 方式来做。
NB 真正的需要是一种从父级触发子实例的事件。
【问题讨论】:
-
@NAO ...您的净化链接...codeburst.io :: Event emitters and listeners in JavaScript
-
只是代替
triggerChild调用emit(这是您编写的触发事件的方法)并且有效?! -
但是,我不明白您为什么需要
classes 或继承——也许parentMethod除外。你的Child不应该有一个开始监听事件的构造函数,充其量它应该有一个单独的方法来做到这一点。但实际上你应该只写const child = new EventEmitter(); child.on(…);(也许把它打包成一个函数)。 -
为什么
Parent甚至是EventEmitter?您似乎从未在其上发出事件。或者更一般地说,为什么Parent和Child实例甚至是两个不同的对象?
标签: javascript