js 实现 EventBus 事件总线

发布时间 2023-07-05 14:30:41作者: 蓓蕾心晴

 EventBus 一般用做单例,EventEmiter 一般在组件或模块内使用

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>事件管理器</title>
</head>

<body>
  <button id="id1">play 绑定1</button>
  <button id="id2">play 绑定2</button>
  <button id="id3">pause</button>
  <button id="id4">unsubcribe play1</button>
  <button id="id5">mute绑定一次</button>
  <script>
    class EventBus {
      constructor() {
        this.eventMap = {}
      }
      subcribe(eventName, callback) {
        if (this.eventMap[eventName]) {
          this.eventMap[eventName].push(callback)
        } else {
          this.eventMap[eventName] = [callback]
        }
      }
      publish(eventName, params) {
        if (this.eventMap[eventName]) {
          this.eventMap[eventName].forEach((fn) => {
            fn && fn(params)
          })
        }
      }
      unsubcribe(eventName, callback) {
        if (this.eventMap[eventName]) {
          // 注意这里一定要重新赋值
          this.eventMap[eventName] = this.eventMap[eventName].filter((fn) => fn !== callback)
          console.log(this.eventMap[eventName])
        }
      }
      once(eventName, callback) {
        // 传参在这里传入
        const cb = (params) => {
          callback && callback(params)
          // 注意这里解绑的封装后的 cb
          this.unsubcribe(eventName, cb)
        }
        // 还是调用监听事件
        this.subcribe(eventName, cb)
      }
    }

    const video = new EventBus();
    const fn = (time) => {
      console.log('play1', time)
    }
    video.subcribe('play', fn)
    video.subcribe('play', (time) => {
      console.log('play2', time)
    })
    video.subcribe('pause', (time) => {
      console.log('pause', time)
    })
    video.once('mute', (time) => {
      console.log('mute', time)
    })
    const id1 = document.getElementById('id1')
    const id2 = document.getElementById('id2')
    const id3 = document.getElementById('id3')
    id1.onclick = () => {
      video.publish('play', new Date().getTime())
    }
    id2.onclick = () => {
      video.publish('play', new Date().getTime())
    }
    id3.onclick = () => {
      video.publish('pause', new Date().getTime())
    }
    id4.onclick = () => {
      video.unsubcribe('play', fn)
    }
    id5.onclick = () => {
      video.publish('mute', new Date().getTime())
    }
  </script>
</body>

</html>