Skip to content
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>发布订阅模式</title>
  </head>
  <body>
    <div class="eg2"></div>

    <script>
      // 创建一个第三方观察着构造函数
      class Observer {
        constructor() {
          // { type_1: [ cb1, cb2 ], type_1: [ cb1, cb2, cb3 ] }
          this.message = {}
        }

        // 1. 向消息队列里面添加内容
        on(type, cb = () => {}) {
          // 判断队列是否存在对应 type
          if (!this.message[type]) {
            // 表示消息队列里面还有注册过
            this.message[type] = []
          }

          // 直接进行 push
          this.message[type].push(cb)
        }

        // 2. 删除消息队列里面的内容
        off(type, cb) {
          // 如果 cb 不存在, 删除整个对应type
          if (!cb) {
            delete this.message[type]
            return
          }

          // 判断订阅类型是否存在
          if (!this.message[type]) return

          // 删除 type 中的消息队列
          this.message[type] = this.message[type].filter((item) => item !== cb)
        }

        // 3. 触发消息队列
        trigger(type) {
          // 判断订阅类型是否存在
          if (!this.message[type]) return

          this.message[type].forEach((cb) => {
            cb()
          })
        }
      }

      const person = new Observer()

      person.on('a', handlerA)
      person.on('a', handlerB)
      person.on('b', handlerB)
      person.on('b', handlerC)

      person.off('a')
      person.off('a', handlerA)

      person.trigger('a')

      console.log(person)

      function handlerA() {
        console.log('handlerA')
      }
      function handlerB() {
        console.log('handlerB')
      }
      function handlerC() {
        console.log('handlerC')
      }
    </script>
  </body>
</html>