在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
我们需要弄清楚,观察者模式和发布订阅模式是不一样的,一张图理解: 两者区别: 1. 观察者 模式只有观察者和被观察者两者,是松耦合 2. 发布订阅模式除了发布者和订阅者外,还有一个调度中心,是解耦的,两者没有直接关系 3. 观察者主要是同步方式实现,二发布订阅模式多数是异步实现,比如消息队列 用typescript 简单实现一个发布订阅模式的类 1 class byEvent { 2 Events: { [key: string]: Array<Function> } //约束示例:{"eventName":[function(){},function(){},.....],......} 3 constructor() { 4 this.Events = {} 5 } 6 /** 7 * 发布/ 触发 8 * @param eventName 9 * @param args 10 */ 11 emit(eventName: string, ...args: any) { 12 let callbackList = this.Events[eventName] || []; 13 callbackList.forEach(fn => fn.apply(this, args)) 14 return this; 15 // 如果用js写,遍历的时候要做一下判断是否是函数,ts 用类型约束,在调用或者编译阶段会检测是否合法 16 // callbackList.map(fn=>{ 17 // if(typeof fn==="function") fn.apply(this,args) 18 // }) 19 } 20 /** 21 * 订阅/监听 22 * @param eventName 23 * @param callback 24 */ 25 on(eventName: string, callback?: Function) { 26 // if(!eventName||typeof eventName !=="string") return ;// 因为用了ts 写,所以这句不用写了,如果是js写,建议加这判断 27 let callbackList = this.Events[eventName] || []; 28 callback && callbackList.push(callback) 29 this.Events[eventName] = callbackList 30 return this; 31 32 } 33 /** 34 * 只订阅一次/监听一次: 35 * 思路: 36 * 1. 重新包装一个回调函数(有名的),进行注册订阅/监听, 37 * 2. 包装函数里面直接调用 once方法的第二个参数回调函数,然后调用off方法 卸载该包装函数 38 * @param eventName 39 * @param callback 40 */ 41 once(eventName: string, callback?: Function) { 42 // if(!eventName||typeof eventName !=="string") return ; 43 let decor = (...args: any[]) => { 44 callback && callback.apply(this, args) 45 this.off(eventName, decor) 46 } 47 this.on(eventName, decor) 48 return this; 49 50 } 51 /** 52 * 卸载/取消 某一个回调监听(不是取消eventName的所有回调监听),主要配合once一起,实例单独调用,无意义 53 * @param eventName 54 * @param callback 55 */ 56 off(eventName: string, callback: Function) { 57 let callbackList = this.Events[eventName] || []; 58 let resCallbacks = callbackList.filter(fn => fn !== callback) 59 this.Events[eventName] = resCallbacks 60 return this; 61 62 } 63 /** 64 * 卸载/取消 指定eventName 的所有订阅/监听 65 * @param eventName 66 * @param callback 67 */ 68 remove(eventName: string, callback?: Function) { 69 this.Events[eventName] = []; 70 callback && callback() 71 return this; 72 73 } 74 75 } 76 77 // 使用示例 78 let o = new byEvent() 79 setInterval(() => { 80 o.emit("name", 123) 81 o.emit("name", 10, 20) 82 o.emit("post", { name: 1212 }, "post") 83 84 }, 1000); 85 setTimeout(() => { 86 o.remove("name", function () { 87 console.log("remove") 88 }) 89 }, 3000) 90 o.once("name", function (...res: any[]) { 91 console.log("once-name1", res) 92 }) 93 o.on("name", function (...res: any[]) { 94 console.log("on-name2", res) 95 }) 96 o.on("post", function (...res: any[]) { 97 console.log("on-post", res) 98 }
|
请发表评论