发布订阅模式和观察者模式

1.发布/订阅模式

  • 订阅者
  • 发布者
  • 信号中心
  假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern)
  个人理解,就是,订阅者是学生家长 , 老师是发布者,公布学生成绩, 班级就是对应每个学生的 信号中心
具体可以看代码
 1 <!DOCTYPE html>
 2 <html lang="cn">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6   <title>发布订阅模式</title>
 7 </head>
 8 <body>
 9   <script>
10     // 事件触发器
11     class EventEmitter {
12       constructor () {
13         // { 'click': [fn1, fn2], 'change': [fn] }
14         //传null,创建的是没有原型的空对象,提升性能
15         this.subs = Object.create(null)
16       }
17 
18       // 注册事件
19       $on (eventType, handler) {
20         this.subs[eventType] = this.subs[eventType] || []
21         this.subs[eventType].push(handler)
22       }
23 
24       // 触发事件
25       $emit (eventType) {
26         if (this.subs[eventType]) {
27           this.subs[eventType].forEach(handler => {
28             handler()
29           })
30         }
31       }
32     }
33 
34     // 测试
35     let em = new EventEmitter()
36     em.$on('click', () => {
37       console.log('click1')
38     })
39     em.$on('click', () => {
40       console.log('click2')
41     })
42 
43     em.$emit('click')
44   </script>
45 </body>
46 </html>

2.观察者模式

  • 观察者(订阅者) -- Watcher

    update():当事件发生时,具体要做的事情

  • 目标(发布者) -- Dep
    subs 数组:存储所有的观察者
    addSub():添加观察者
    notify():当事件发生,调用所有观察者的 update() 方法
  • 没有事件中心
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6   <title>观察者模式</title>
 7 </head>
 8 <body>
 9   <script>
10     // 发布者-目标
11     class Dep {
12       constructor () {
13         // 记录所有的订阅者
14         this.subs = []
15       }
16       // 添加订阅者
17       addSub (sub) {
18         if (sub && sub.update) {
19           this.subs.push(sub)
20         }
21       }
22       // 发布通知
23       notify () {
24         this.subs.forEach(sub => {
25           sub.update()
26         })
27       }
28     }
29     // 订阅者-观察者
30     class Watcher {
31       update () {
32         console.log('update')
33       }
34     }
35 
36     // 测试
37     let dep = new Dep()
38     let watcher = new Watcher()
39 
40     dep.addSub(watcher)
41 
42     dep.notify()
43   </script>
44 </body>
45 </html>
总结:
  • 观察者模式是由具体目标调度,比如当事件触发,Dep 就会去调用观察者的方法,所以观察者模式的订阅者与发布者之间是存在依赖的。
  • 发布/订阅模式由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。

 

 

posted on 2022-12-13 22:53  菜鸟小于  阅读(137)  评论(0编辑  收藏  举报