发布订阅模式
发布订阅模式是一种对象之间一对多
的依赖关系(利用消息队列
)
当一个对象的状态发生变化
,所有依赖它的对象
都会得到状态改变的通知
订阅者
把自己想订阅的事件
注册到调度中心
发布者
发布该事件到调度中心
,当该事件触发的时候,会由调度的中心
统一调度订阅者
注册到调度中心的处理代码
角色
发布者
: 负责发布事件或者消息
订阅者
: 订阅了发布者发布的事件或消息,并在事件发生时做出响应
订阅发布模式的基本思想就是解耦发布者和订阅者之间的关系,发布者不需要只知道订阅者的存在,订阅者不需要知道发布者的存在。通过一个中介(事件总线,事件管理器)进行通信
优点缺点
- 优点
- 解耦性:发布者和订阅者是松散耦合的,不需要知道彼此的存在
- 灵活性:订阅发布模式允许系统之间不同部分在不影响彼此的情况下同行。
- 拓展性:通过订阅发布模式,可以新增新的订阅和发布者
- 缺点
- 增加消耗,创建结构和缓存订阅这两个过程都需要消耗计算和内存资源
- 增加复杂度,订阅者被缓存在一起,多个订阅者和发布者层层嵌套,程序将变得难以调试和追踪
实现
- 手动实现
- js库: Nodejs:
EventEmitter
Jquery: 事件系统
订阅发布
- 简单的事件触发和订阅机制
class EventEmitter {
constructor() {
this.handles = {} // 事件队列
}
// 订阅事件
on(eventName, callback) {
if (!this.handles[eventName]) {
this.handles[eventName] = []
}
this.handles[eventName].push(calllback)
}
// 触发事件
emit(eventName) {
if (this.handles[eventName]) {
const handles = this.handles[eventName]
handles.forEach(callback => {
callback()
})
}
}
}
const emitter = new EventEmitter()
emitter.on('onShell', () => {
console.log('hello')
})
emitter.on('onShell', () => {
console.log('world')
})
emitter.emit('onShell')
在上述代码的基础上新增一个取消订阅的功能
off(eventName, cb) {
const handles = this.handles[eventName]
const index = handles && handles.indexOf(cb)
if (index !== -1 ) {
handles.splice(index, 1)
}
}
在上述代码中实现仅订阅一次的事件
once(eventName, cb) {
if (this.handles[eventName] && this.handles[eventName].indexOf(cb) !== -1) {
return
}
this.on(eventName, cb)
}
学习了掘金上的博主https://juejin.cn/post/7356055073586151475?searchId=202404221111586D858AF5D43472053BDE