订阅者把自己想要订阅的事件注册到调度中心,当发布者发布该事件到调度中心,由调度中心调度订阅者注册到调度中心的处理代码。
实现思路
- 创建一个类EventCenter
- 定义一个事件处理中心handlers
- 实现on方法,把函数添加到事件中心,订阅者把事件都注册到调度中心
- emit, 根据事件type去执行对应事件中心的函数=>发布者发布事件到调度中心,调度中心处理代码
- 取消订阅off
class EventCenter{ // 1. 定义一个世界容器,用来装事件数组 constructor(){ this.handlers = {}; } //2.添加事件方法,参数:事件名,事件方法 on(type, handler){ if(!this.handlers[type]){ this.handlers[type] = []; } // 存入事件 this.handlers[type].push(handler) } //3.触发事件,参数:事件名 事件参数 emit(type, parmas){ if(!this.handlers[type]){ return new Error('事件无效') } // 触发事件,,执行该事件类型上的所有处理函数 this.handlers[type].forEach(fn => fn(...parmas) } // 4/移除事件,参数:事件名, 要删除的事件,若无第二个参数,则删除该事件的订阅和发布 off(type, handler){ if(!this.handlers[type]){ return new Error('事件无效') } if(!handler){ delete this.handlers[type] }else { // 找到要删除的事件处理函数 let index = this.handlers[type].findIndex(el => el === handler) if(index === -1){ return new Error(`该${type}无绑定事件`) } // 移除事件 this.handlers[type].splice(index, 1) if(this.handlers[type].length === 0){ delete this.handlers[type] } } } // 事件的单次订阅once, 需要在回调函数执行后,取消订阅当前事件,所以要对传入的回调包一层, once(type, handler){ const one = (...args) => { handler(...args) this.off(type, one) } one.initialCallback = handler this.on(type, one) } }