我们需要弄清楚,观察者模式和发布订阅模式是不一样的,一张图理解:
两者区别:
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 }
查看更多关于使用typescript 写一个简单的事件监听/发布订阅模式的类的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did223222