前端手写(二十一)——手写event模块

x33g5p2x  于2022-04-02 转载在 其他  
字(1.1k)|赞(0)|评价(0)|浏览(410)

一、写在前面
手写event模块,我们需要手写一些方法,比如说:addEventListener,removeListener,onceremoveAllListener,emit
二、手写

function EventEmitter() {
  this.events = new Map()
}

//需要封装的方法addListener, removeListener, once, removeAllListener, emit
const wrapFunc = function (fn, once = false) {
  return {
    callback: fn,
    once
  }
}

EventEmitter.prototype.addListener = function (type, fn, once = false) {
  const handler = this.events.get(type)
  if (!handler) {
    this.events.set(type, [wrapFunc(fn, once)])
  } else {
    handler.push(wrapFunc(fn, once))
  }
}

EventEmitter.prototype.removeListener = function (type, fn) {
  const handler = this.events.get(type)
  if (!handler) return
  for (let i = 0; i < handler.length; i++) {
    if (handler[i].callback === fn) {
      handler.splice(i, 1)
      i--
    }
  }
  if (handler.length === 0) {
    this.events.delete(type)
  }
}

EventEmitter.prototype.once = function (type, fn) {
  this.addEventListener(type, fn, true)
}

EventEmitter.prototype.emit = function (type, ...args) {
  const handler = this.events.get(type)
  if (!handler) return
  for (let item of handler) {
    item.callback.apply(this, args)
    this.removeListener(type, item.callback)
  }
}

EventEmitter.prototype.removeAllListener = function (type) {
  this.events.delete(type)
}

相关文章