eventEmitter简单实现

时间:2025-03-28 10:26:13
class EventEmitter { // 初始化事件对象 constructor() { this.events = {} } // 事件监听,监听的过程就是订阅,也就是把订阅者收集起来 on(eventName, callback) { // 如果不存在该事件,则进行数组初始化 if (!this.events[eventName]) { this.events[eventName] = [] } // 存在对应的数组继续订阅收集,则把事件推入收集数组 this.events[eventName].push(callback) // 返回自身 方便链式调用 return this } // 事件触发,触发的过程就是发布,也就是通知订阅者 emit(eventName, ...args) { // 不存在该事件,则不触发 if (!this.events[eventName]) { return this } // 存在则对收集的订阅者一一通知(函数一一执行) const fns = this.events[eventName] // 执行的时候绑定自身this fns.forEach(fn => fn.apply(this, args)) // 返回自身 方便链式调用 return this } // 解绑事件,取消订阅,将订阅者从订阅者数组中移除 remove(eventName, callback) { if (!this.events[eventName]) { return this; } // 没有指定解绑事件? 就是没有指定对应的订阅者,那么移除所有订阅者 if (!callback) { this.events[eventName] = null return this } // 否则找到该事件, 就是对应的订阅者,将其移除 const index = this.events[eventName].indexOf(callback); this.events[eventName].splice(index, 1); return this; } // 单次绑定事件,执行完后解绑 once(eventName, callback) { const only = () => { callback.apply(this, arguments); this.remove(eventName, only); }; this.on(eventName, only); return this; } } const emt = new EventEmitter() // 订阅者1 const listener1 = function (...args) { console.log('意林的第一个订阅者', ...args); } // 订阅者2 const listener2 = function (...args) { console.log('意林的第二个订阅者', ...args); } // 收集订阅者,将杂志命名为'yilin' emt.on('yilin', listener1) emt.on('yilin', listener2) // 500ms后订阅者1不想要该杂志了,进行取消订阅 setTimeout(() => { emt.remove('yilin', listener1) }, 500) // 1秒后意林杂志更新了,进行发布,通知订阅者,这时由于订阅者1取消订阅了,所以订阅者1就不会执行了 setTimeout(() => { emt.emit('yilin', 'hello world') }, 1000) // 打印结果为:1s后打印 `意林的第二个订阅者 hello world`