Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript设计模式(五):发布-订阅模式 #25

Open
yangrenmu opened this issue Apr 28, 2020 · 0 comments
Open

JavaScript设计模式(五):发布-订阅模式 #25

yangrenmu opened this issue Apr 28, 2020 · 0 comments
Labels

Comments

@yangrenmu
Copy link
Owner

定义

发布-订阅模式:又称为观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都将得到通知。

这个有点类似于我们平时关注的公众号,公众号发布消息,所有订阅了的人,都会收到消息。

实现一个简单的发布订阅模式

const Event = function () {
  this.obj = {}
}

Event.prototype.on = function (eventType, fn) {
  if (!this.obj[eventType]) {
    this.obj[eventType] = []
  }
  this.obj[eventType].push(fn)
}

Event.prototype.emit = function () {
  const eventType = Array.prototype.shift.call(arguments)
  const arr = this.obj[eventType]
  for (let i = 0; i < arr.length; i++) {
    arr[i].apply(arr[i], arguments)
  }
}

const ob = new Event()

ob.on('say', function (msg) {    // 订阅
  console.log(msg)               // hello
})

ob.emit('say', 'hello')          // 发布

当我们将原本emit里触发的函数缓存下来,放到on中触发,就可以实现先发布函,后订阅。就像下面这样。

const Event = function () {
  this.obj = {}
  this.cacheList = []
}

Event.prototype.on = function (eventType, fn) {
  if (!this.obj[eventType]) {
    this.obj[eventType] = []
  }
  this.obj[eventType].push(fn)
  for (let i = 0; i < this.cacheList.length; i++) {
    // 订阅时,执行之前发布时,缓存下来的 cache
    this.cacheList[i]()
  }
}

Event.prototype.emit = function () {
  const arg = arguments
  const that = this
  function cache() {
    var eventType = Array.prototype.shift.call(arg)
    var arr = that.obj[eventType]
    for (let i = 0; i < arr.length; i++) {
      arr[i].apply(arr[i], arg)
    }
  }
  // 发布时,将 cache 缓存下来
  this.cacheList.push(cache)
}

const ob = new Event()
ob.emit('say', 'hello')
ob.on('say', function (msg) {
  console.log(msg) // hello
})

总结

发布订阅模式主要的好处就是对象之间的解耦,帮助我们写出更松耦合的代码。缺点是订阅者的创建是消耗一定的时间和内存的。使用过多也是难以维护的。

@yangrenmu yangrenmu added the mode label Apr 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant