Skip to content

实现一个 EventEmitter #45

Open
@myLightLin

Description

@myLightLin

前端的设计模式里,发布-订阅模式 可以说是应用最广泛也经常在实践中看见它们的身影。发布-订阅模式的主要思想是:A 设置一个订阅器,提供不同的 type 供 B,C,D 等订阅,然后当某种 type 的内容有更新时,A 就会通知到所有订阅了该内容的 B,C,D 等人。发布订阅模式主要有以下几个方法:

  • on: 注册事件监听的回调函数
  • emit: 触发事件,通知所有回调执行
  • off: 移除事件监听
  • once: 注册事件监听,但是只监听一次。这个方法可以用来解决缓存雪崩问题:当大量请求涌入数据库,可以通过状态锁来保证只执行一个查询请求,但是状态锁会导致后续进来的查询请求无法应用。因此可以引入事件队列,利用 once 只触发一次的效果来实现请求去重。

代码

// 实现 EventEmiter
class EventEmitter {
  constructor() {
    this.events = {}
  }
  
  emit(type, ...args) {
    this.events[type].forEach(fn => {
      fn(...args)
    })
    return true
  }
  
  on(type, handler) {
    this.events[type] = this.events[type] || []
    this.events[type].push(handler)
    return this
  }
  
  off(type, handler) {
    const lis = this.events[type]
    if (!lis) return this
    for (let i = lis.length; i > 0; i--) {
      if (lis[i] === handler) {
        lis.splice(i, 1)
        break
      }
    }
    return this
  }
  
  once(type, handler) {
    this.events[type] = this.events[type] || []
    const onceWrapper = () => {
      handler()
      this.off(type, onceWrapper)
    }
    this.events[type].push(onceWrapper)
    return this
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions