发布订阅 观察者模式

70 阅读1分钟

发布订阅

class EventTarget {
  constructor () {
    this.handlers = {};
  }
  on (type, handler) {
    if (typeof this.handlers[type] === 'undefined') {
      this.handlers[type] = []
    }
    this.handlers[type].push(handler)
  }
  emit (type, ...args) {
    if (this.handlers[type]) {
      this.handlers[type].forEach( handler =>{
        handler(...args)
      })
    }
  }
  off (type, handler) {
    if (this.handlers[type]) {
      let i = this.handlers[type].findIndex( item => item === handler)
      if (i !== -1){
        this.handlers[type].splice(i, 1)
      }
    if (this.handlers[type].length === 0) {
        delete this.handlers[type]
      }
    }
  }
  offAll (type) {
    if (this.handlers[type]) {
      delete this.handlers[type]
    }
  }
}

// EventTarget 类型有一个单独的属性 handlers,用于储存事件处理程序。
// 还有四个方法: on(),用于注册给定类型事件的事件处理程序;emit(),用于触发一个事件;
// off(),用于注销某个事件类型的某个事件处理程序。
// offAll(),用于注销某个事件类型的所有事件处理程序。

// 创建事件管理器实例
const target = new EventTarget()
function handleMessage (message) {
  console.log('Message Receive: ', message)
}
// 注册一个message事件监听者
target.on('message', handleMessage)
// 发布事件message
target.emit('message', '吃饭了')

// 测试移除事件监听
const toBeRemovedListener = function() { console.log('我是一个可以被移除的监听者') }
target.on('testoff', toBeRemovedListener)
target.emit('testoff')
target.off('testoff', toBeRemovedListener)
target.emit('testoff') // 此时事件监听已经被移除,不会再有console.log打印出来了

// 测试移除chifan的所有事件监听
target.offAll('message')
console.log(target) // 此时可以看到ee.listeners已经变成空对象了,再emit发送target事件也不会有反应了

观察者模式

class Subscribe {
  constructor () {
    this.observerList = []
  }
  addObserver (observer) {
    this.observerList.push(observer)
  }
  notify() {
    this.observerList.forEach(observer => {
      observer.update()
    })
  }
}

class Observer {
  constructor (fn) {
    if (typeof fn ===  'function') {
      this.fn = fn
    } else {
      throw new Error('Observer构造器必须传入函数类型!')
    }
  }
  update () {
    this.fn()
  }
}

const observerCallback = function() {
  console.log('我被通知了')
}
const observer = new Observer(observerCallback)

const subscribe = new Subscribe();
subscribe.addObserver(observer);
subscribe.notify();

参考: juejin.cn/post/684490…