手写发布订阅模式

什么是发布订阅模式

概念

发布-订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。

订阅者(Subscriber)把自己想订阅的事件 注册(Subscribe)到调度中心(Event Channel);

发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由 调度中心 统一调度(Fire Event)订阅者注册到调度中心的处理代码。

典型例子

公众号;各种关注(b站/小红书/微博)

dom 中的 addEventListener 实际上也使用了发布订阅,我们不知道用户什么时候会 click,于是订阅了 btn 的 click 事件,当用户点击了按钮,就会发布。

1
2
3
document.getElementById('btn').addEventListener('click',function(){
// 执行代码
})

vue 中的 数据响应式 以及 全局事件总线(eventBus)

优缺点

优点

  • 低耦合:消息的发布者和订阅者在开发的时候完全不需要事先知道对方的存在

  • 通信简洁:不需要为每一个消息的订阅者准备专门的消息格式

缺点

  • 创建订阅者需要消耗一定时间和内存
  • 多个发布者和订阅者嵌套时,难维护跟踪

手写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Event {
events = {}

// 触发事件
emit(type, ...args) {
const listeners = this.events[type]
for (const listener of listeners) {
listener(...args)
}
}

// 绑定事件
on(type, listener) {
this.events[type] = this.events[type] || []
this.events[type].push(listener)
}

// 只触发一次
once(type, listener) {
const callback = (...args) => {
this.off(type, callback)
listener(...args)
}
this.on(type, callback)
}

// 事件解绑
off(type, listener) {
this.events[type] = this.events[type] || []
this.events[type] = this.events[type].filter((item) => {
item !== listener
})
}
}

参考

https://juejin.cn/post/7052637219084828680

https://blog.csdn.net/Shockang/article/details/115712780


手写发布订阅模式
http://example.com/2022/11/01/手写发布订阅模式/
Author
John Doe
Posted on
November 1, 2022
Licensed under