JS原生实现EventEmitter事件队列
2023-03-01 本文已影响0人
斐硕人
EventEmitter 是什么
- Node.js 的
events 模块
对外提供了一个EventEmitter 对象
,用于对 Node.js 中的事件进行统一管理。- Node.js 采用了事件驱动机制, EventEmitter 就是 Node.js 实现事件驱动的基础,Node.js 中几乎所有的模块都继承了这个类,以实现异步事件驱动架构。
- Node.js 中几乎所有的模块都继承了这个类,以实现异步事件驱动架构。浏览器事件(如鼠标单击click,键盘事件keyDown)等都是该模式的例子
核心代码-参考1
使用 events 模块,对事件数组进行管理,
on
添加进事件队列 addListener
emit
执行
off
关闭 removeListener
once
只执行一次,结束后 remove
class EventEmitter {
constructor(){
this.events = {}
}
on(event, listener){
let listeners = this.events[event] || []
listeners.push(listener)
this.events = listeners
return this
}
emit(event, ...args){
let listeners = this.events[event]
listeners.forEach(listener => {
listener(...args)
});
return this
}
off(event, listener){
let listeners = this.events[event]
this.events[event] = listeners && listeners.filter(fn => fn !== listener)
return this
}
once(event, listener){
let fn = function(...args){
listener(...args)
this.off(event, listener)
}
this.on(event, fn)
return this
}
}
优化-参考2
添加事件合法性校验等
function EventEmitter() {
this.__events = {};
}
EventEmitter.VERSION = "1.0.0";
EventEmitter.prototype.on = function (eventName, listener) {
// 验证参数
if (!eventName && !listener) {
return;
}
// 回调的litener是否是函数
if (!isValidKistener(listener)) {
throw new TypeError("listener must be a function");
}
const events = this.__evnets;
const listeners = (events[eventName] = evnets[eventName] || []);
const listenerIsWrapped = typeof listener === "object";
// 不重复添加事件,判断是否有相同
if (indexOf(listeners.listener) === -1) {
listeners.push(
listenerIsWrapped
? listener
: {
listener: listener,
once: false,
}
);
}
return this;
};
//判断是否是合法的listener
const isValidListener = (listener) => {
if (typeof listener === "function") {
return true;
} else if (listener && typeof listener === "object") {
return isValidListener(listener.listener);
} else {
return false;
}
};
// 判断新增自定义事件是否存在
const indexOf = (array, item) => {
let result = -1;
item = typeof item === "object" ? item.listener : item;
for (let i = 0; i < array.length; i++) {
if (array[i].listener === item) {
result = i;
break;
}
}
return result;
};
设计模式
采用了发布-订阅者模式
发布-订阅模式
其实是一种对象间一对多
的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。
- 订阅者(Subscriber)把自己想订阅的事件 注册(Subscribe)到调度中心(Event Channel);
- 当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由 调度中心 统一调度(Fire Event)订阅者注册到调度中心的处理代码
相关文章