前端笔记JS篇1:手写EventBus

116 阅读1分钟

EventBus事件总线作为前端面试经常提到的知识点,发布订阅模式。理解了EventBus可以在项目中更好的进行全局通信

相关代码:

export default function eventBus() {
  const all = new Map()
  return {
  
    all,
    
    on(type, handler) {
      const handlers = all.get(type) // 获取type类型的事件数组
      if (handlers) { // 如果有事件数组,则将事件继续push到数组中
        handlers.push(handler)
      } else {
        all.set(type, [handler]) // 如果没有则新建
      }
    },
    
    off(type, handler) {
      const handlers = all.get(type)
      if (handlers) {
        if (handler) {
          // handlers中存在handler话,删除,不存在则不删除
          handlers.splice(handlers.indexOf(handler) >>> 0, 1) // -1 >>> 0 = 4294967295  2 >>> 0 = 2
        } else { // 如果没有传入handler,则清空全部handler
          all.set(type, [])
        }
      }
    },
    
    emit(type, evt) {
      let handlers = all.get(type)
      if (handlers) {
        handlers.slice().map((handler) => {
          handler(evt)
        })
      }

      handlers = all.get('*')
      if (handlers) {
        handlers.slice().map((handler) => {
          handler(type, evt)  // 监听全部事件时,回调函数有两个参数,第一个为触发事件的type
        })
      }
    }
  }
}

使用:

// a.js
const bus = eventBus()
export default bus

// b.js
import bus from 'a.js'

bus.on('*', (type, arg) => console.log(type, arg))
bus.on('read', (arg) => console.log('read' + arg))
bus.emit('read', 'javascript')


function ab() {
  console.log('ab')
}
bus.on('hh', ab)
bus.on('hh', (arg) => {
  console.log(arg)
})
bus.off('hh', ab)
bus.emit('hh', 1)