我正在参加「掘金·启航计划」
发布订阅模式和观察者模式是我们前端最常见的两种模式,我之前就会发出观察者模式不就是发布订阅吗?这样的疑问。
发布订阅模式
发布订阅模式,主要分成两个部分:on(订阅)和 emit(发布)
- on :就是把一些函数维护到一个数组中
- emit :就是让数组中的方法依次执行
- 发布和订阅没有明显的关联,靠中介event来实现
let event = {
arr: [],
on (fn) { //订阅
this.arr.push(fn)
},
emit () { //发布
this.arr.forEach(fn => fn())
}
}
event.on(function () {
console.log('读取了一个');
})
event.on(function () {
if (Object.keys(school).length === 2) {
console.log(school);
}
})
let school = {}
school.name = 'lxh'
event.emit()
school.age = '22'
event.emit()
输出结果:
读取了一个
读取了一个
{ name: 'lxh', age: '22' }
观察者模式
观察者模式,主要分成两个部分:subject(被观察者)和 observer(观察者)
- 观察者需要放到被观察者中,被观察者的状态发生变化需要通知观察者
- 内部也是基于发布订阅模式,收集观察者,状态变换后通知观察者
class subject { //被观察者
constructor(name) {
this.name = name
this.state = '开心的'
this.observers = []
}
attach (o) {
this.observers.push(o)
}
setState (newState) {
this.state = newState
this.observers.forEach(o => o.update(this))
}
}
class observer { //观察者
constructor(name) {
this.name = name
}
update (baby) {
console.log('当前' + this.name + '被通知了', '当前状态' + baby.state);
}
}
let baby = new subject('小宝宝')
let parents = new observer('爸爸')
let mother = new observer('妈妈')
baby.attach(parents)
baby.attach(mother)
baby.setState('被欺负了')
输出结果:
当前爸爸被通知了 当前状态被欺负
当前妈妈被通知了 当前状态被欺负
总结
发布订阅模式:
- 发布者的发布动作和订阅者的订阅动作相互独立,无需关注对方,消息派发由发布订阅中心负责
观察者模式:
- 观察者主动申请加入被观察者的列表
- 被观察者主动将观察者加入列表