Skip to content

手写一个发布-订阅模式 #110

Description

@sisterAn
class EventEmitter {
  constructor() {
    // 初始值为空对象
    this.listeners = Object.create(null)
  }
  
  // 注册事件
  on = (event, listener) => {
    // this.bindEvent(event, listener, false)
    if (!event || !listener) {
      return
    }
    if (this.listeners[event]) {
        //如果有就放一个新的
        this.listeners[event].push(listener)
    } else {
        //如果没有就创建一个数组
        this.listeners[event] = [listener]
    }
  }
  
  // 只订阅一次
  once = (event, listener) => {
    // this.bindEvent(event, listener, true)
    function one() {
        // 在one函数运行原来的函数,只有将one清空
        listener.apply(this, arguments)
        // 先绑定 执行后再删除
        this.off(event)
    }
      this.on(event, one)
      //此时emit触发会执行此函数,会给这个函数传递rest参数
  }
  
  // 发布事件
  emit = (event, ...args) => {
    if (!this.hasBind(event)) {
      console.warn(`this event: ${event} don't has bind listener.`)
      return
    }

    this.listeners[event].forEach(listener => listener.call(this, ...args))
  }
  
  // 取消订阅
  off = (event, listener) => {
    if (!this.hasBind(event)) {
      console.warn(`this event: ${event} don't exist.`)
      return
    }

    // remove all listener
    if (!listener) {
      delete this.listeners[event]
      return
    }

    // remove specific listener
    this.listeners[event] = this.listeners[event].filter(item => item !== listener)
  }

  hasBind = event => {
    return this.listeners[event]
      && this.listeners[event].length
  }
}

// 测试
const baseEvent = new EventEmitter()
function cb(value){
    console.log("hello "+value)
}
baseEvent.once("click",cb)
// baseEvent.off("click")
baseEvent.emit("click",'2020')
// hello 2020
console.log(baseEvent.listeners)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions