共计 1777 个字符,预计需要花费 5 分钟才能阅读完成。
公布 / 订阅模式
- 订阅者
- 发布者
- 事件核心
咱们假设,存在一个“事件核心”,某个工作执行实现,就向事件核心“公布”(publish)一个事件,其余工作能够向事件核心“订阅”(subscribe)这个事件,从而晓得什么时候本人能够执行。这就叫做“公布 / 订阅模式”(publish-subscribe pattern)
// vue 实现的地方事件总线
let vm = new Vue()
// {'dataChange': [fn1, fn2], 'handleData: [fn]' }
// 注册事件(订阅音讯)vm.$on('dataChange', () => {console.log('dataChange1')
})
vm.$on('dataChange', () => {console.log('dataChange2')
})
// 触发事件(公布音讯)vm.$emit('dataChange')
上面实现一个公布订阅:
// 手写实现公布订阅
// 事件触发器
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 (enventType) {
// 先判断是否有以后事件,有则执行,没有则不作解决
if(this.subs[eventType]){
// 遍历数组调用事件函数
this.subs[eventType].forEach(handler => {handler()
})
}
}
}
const 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() 办法
- 没有事件核心
对于为什么指标(发布者)用 Dep 示意,是因为 Dep 是 dependence(依赖)的缩写。因为 Watcher 观察者(订阅者)须要依赖 Dep 能力理解数据的变动,没有 Dep,Watcher 基本不可能晓得数据产生了变动,当有数据变动产生时,Dep 会告诉 Watcher。
// 发布者 - 指标
class Dep {constructor () {
// 记录所有的订阅者
this.subs = []}
// 增加订阅者
addSub (sub) {
// 在增加之前,要确保订阅者存在且具备 update 办法
if (sub && sub.update) {this.subs.push(sub)
}
}
// 公布告诉
notify () {
// 找到所有的订阅者并调用它们的 update 办法
this.subs.forEach(sub => {sub.updatre()
})
}
}
// 订阅者 - 观察者
class Watcher {update () {console.log('update')
}
}
let dep = new Dep()
let watcher = new Watcher()
dep.addSub(watcher)
dep.notify()
总结
- 观察者模式 是由具体指标调度,比方当事件触发,Dep 就会去调用观察者的办法,所以观察者模式的订阅者和发布者之间是存在依赖的
- 公布 / 订阅模式 由对立调度核心(事件核心)调用,因而发布者和订阅者不须要晓得对方的存在
事件核心隔离了发布者和订阅者,去除它们之间的相互依赖。观察者模式中,指标与观察者是相互依赖的,而公布订阅模式中,多了个事件核心。事件核心是隔离发布者和订阅者的,缩小发布者和订阅者的依赖关系,会变得更加灵便。
正文完
发表至: javascript
2020-10-23