EventDispatch实现

278 阅读1分钟

1. EventDispatch

EventDispatch即事件调度,实际上应用了订阅发布模式,有四个功能:

  1. 添加订阅者:addEventListener(event, listener)
  2. 删除订阅者:removeEventListener(event, listener)
  3. 调用事件:dispatchEvent(event)
  4. 查询对象是否订阅了事件:hasEventListener(event, listener)

2. 实现代码

talk is cheap, show me the code

class EventDispatcher {
  constructor() {
    this.listeners = {} // 事件订阅控制器
  }
  addEventListener(event, cb) {
    let listeners = this.listeners
    if (!listeners[event]) listeners[event] = [] // 建立事件订阅队列
    
    if (!listeners[event].includes(cb)) listeners[event].push(cb) // 向队列添加事件订阅者
  }
  removeEventListener(event, cb) {
    if (!this.listeners[event]) return
    let cbQueue = this.listeners[event]
    
    let idx = cbQueue.indexOf(cb)
    idx > -1 && cbQueue.splice(idx, 1) // 移除事件订阅者
  }
  dispatchEvent(event) {
    if (!this.listeners[event]) return
    let cbQueue = this.listeners[event]

    for (let cb of cbQueue) cb() // 通知事件的每一个订阅者
  }
  hasEventListener(event, cb) {
    let listeners = this.listeners
  
    return listeners[event] && listeners[event].includes(cb)
  }
}

// test
let eventDispatcher = new EventDispatcher()
let cb1 = () => console.log(1)
let cb2 = () => console.log(2)
eventDispatcher.addEventListener('event1', cb1)
eventDispatcher.addEventListener('event1', cb2)

eventDispatcher.events // { event1: [ cb1, cb2 ] }
eventDispatcher.dispatchEvent('event1') // 1 2
eventDispatcher.removeEventListener('event1', cb1)
eventDispatcher.hasEventListener('event1', cb1) // false
eventDispatcher.dispatchEvent('event1') // 2

参考

three/core/EventDispatcher.js