设计模式

52 阅读1分钟

发布订阅者模式

/**
 * 常见的发布订阅模式:
 *
 * vue2的eventbus和vue3的mitt
 * addEventListener
 */
class Bus {
  event
  constructor() {
    this.event = new Map()
  }

  on(str, cb) {
    if (this.event.has(str)) {
      const cbList = this.event.get(str)
      cbList && cbList.push(cb)
    } else {
      this.event.set(str, [cb])
    }
  }
  off(str, cb) {
    if (this.event.has(str)) {
      const cbList = this.event.get(str)
      cbList && cbList.splice(cbList.indexOf(cb), 1)
    }
  }
  emit(str, ...arg) {
    const cbList = this.event.get(str)
    for (let i = 0; i < cbList.length; i++) {
      cbList[i](...arg)
    }
  }
  once(str, cb) {
    const callback = (...arg) => {
      cb(...arg)
      this.off(str, cb)
    }

    this.on(str, callback)
  }
}

document.addEventListener("click", () => {
  console.log(1)
})

const bus = new Bus()

// on
// bus.on("msg", () => {
//   console.log("1")
// })
// bus.on("msg", () => {
//   console.log("2")
// })

// emit
// bus.emit("msg", 1)

// off
// bus.off("msg", () => {
//   console.log(2)
// })

// once
// bus.once("msg2", (res) => console.log(res))
// bus.emit("msg2", 1)
// bus.emit("msg2", 1)
// bus.emit("msg2", 1)
// bus.emit("msg2", 1)
// bus.emit("msg2", 1)