我们需要弄清楚,观察者模式和发布订阅模式是不一样的,一张图理解:
两者区别:
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://www.haodehen.cn/did223222