发布/订阅 模式
- 发布/订阅模式
-
订阅者
-
发布者
-
信号中心
我们假定存在一个“信号中心”,某个任务执行完成,就向信号中心“发布(publish)”一个信号, 其他任务可以向信号中心 “订阅(subscribe)” 这个信号, 从而知道什么时候自己可以执行, 这就叫“发布/订阅模式(publish- subscribe- pettern)
-
自定义实现 vue 中的发布订阅模式。
// 事件触发器
class EventEmitter {
constructor () {
// {'click': [fn1,fn2], 'change': [fn]}
this.subs = Object.create(null)
}
// 注册事件
$on(eventType, handler) {
this.subs[eventType] = this.subs[eventType] || []
this.subs [eventType].push(handler)
}
// 触发事件
$emit(eventType) {
if(this.subs[eventType]){
this.subs[eventType].forEach(handler => {
handler()
})
}
}
}
// 测试
let em = new EventEmitter()
em.$on('click', ()=>{
console.log('click1')
})
em.$on('click', ()=>{
console.log('click2')
})
em.$emit('click')
观察者模式
- 观察者(订阅者) - watcher
- update(): 当事件发生时,具体要做的事情
- 目标(发布者) - Dep
- subs数组: 储存所有的观察者
- addSub(): 添加观察者
- notify(): 当事件发生, 调用所有观察者的 update() 方法
实现观察者模式
// 发布者-目标
class Dep {
constructor () {
// 记录所有的订阅者
this.subs = []
}
// 添加观察者
addSub (sub) {
if(sub && sub.update) {
this.subs.push(sub)
}
}
// 发布通知
notify () {
this.subs.forEach(sub => {
sub.update()
})
}
}
// 订阅者-观察者
class Watcher {
update(){
console.log('update')
}
}
let dep = new Dep()
let watcher = new Watcher()
dep.addSub(watcher)
dep.notify()
总结
-
观察者模式是由具体目标调用, 比如当事件触发, Dep 就会去调用观察者的方法, 所以观察者模式的订阅者与发布者之间是存在依赖的
-
发布/订阅模式由统一调度中心调用, 因此发布者和订阅者不需要知道对方的存在