发布订阅模式和观察者模式

179 阅读2分钟

我正在参加「掘金·启航计划」

发布订阅模式和观察者模式是我们前端最常见的两种模式,我之前就会发出观察者模式不就是发布订阅吗?这样的疑问。

发布订阅模式

发布订阅模式,主要分成两个部分: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('被欺负了')

输出结果:

当前爸爸被通知了 当前状态被欺负
当前妈妈被通知了 当前状态被欺负

总结

发布订阅模式:

  • 发布者的发布动作和订阅者的订阅动作相互独立,无需关注对方,消息派发由发布订阅中心负责

观察者模式:

  • 观察者主动申请加入被观察者的列表
  • 被观察者主动将观察者加入列表