EventEmitter
class EventEmitterDemo {
constructor() {
this.events = {}; // 映射事件名和处理函数
// this.maxListeners = 10; // 默认单个事件的最大监听器数量
}
// 将处理函数添加到事件的回调队列后
on(name, cb) {
if (!this.events[name]) {
this.events[name] = [];
}
this.events[name].push(cb);
return this; // 支持链式调用
}
// 将处理函数添加到事件的回调队列前
prependListener(name, cb) {
if (!this.events[name]) {
this.events[name] = [];
}
this.events[name].unshift(cb);
return this;
}
// 触发事件,执行回调函数
emit(name, ...args) {
const listeners = this.events[name];
if (!listeners || listeners.length === 0) return false;
// 用副本遍历,避免 once 在回调中移除自身导致迭代错乱
for (const cb of [...listeners]) {
cb.apply(this, args);
}
return true;
}
// 移除某一个回调函数
off(name, cb) {
const listeners = this.events[name];
if (!listeners) return this;
// 同时兼容 once 包装后的监听器(listener.origin)
this.events[name] = listeners.filter(
(listener) => listener !== cb && listener.origin !== cb
);
return this;
}
// 为指定事件注册一个单次监听器,监听器至多只会触发一次,触发后立即解除该监听器
once(name, cb) {
const onceCb = (...args) => {
cb.apply(this, args);
this.off(name, onceCb);
};
// 关键:把原始 cb 挂到包装函数上,方便 off(name, cb) 时也能移除 once 监听
onceCb.origin = cb;
this.on(name, onceCb);
return this;
}
}
// const EventEmitter = require('events');
let event = new EventEmitterDemo();
let demoFunc = function () {
// 绑定事件和处理函数
console.log("demo boom!");
};
let demo2Func = function () {
console.log("demo2 boom!");
};
let demo3Func = function () {
console.log("demo3 boom!");
};
event.once("demo", demoFunc);
event.on("demo", demo2Func);
event.prependListener("demo", demo3Func);
event.off("demo", demo2Func);
console.log("set fire to demo");
setTimeout(function () {
event.emit("demo");
}, 1000);
setTimeout(function () {
event.emit("demo");
}, 2000);
手写 eventbus,参考