由于前不久做某厂的前端笔试题,遇到这道题没能实现出来,于是在此进行总结记录。
EventEmitter是Node.js中提供的一个监听器类,类似于前端vue中的eventBus事件总线。
其原理主要是发布订阅者模式。
 用订阅杂志进行类比,所有的杂志就是一个大对象: events: {}
 意林是其中一款杂志,那么意林就是events对象中的一个属性,值为数组(因为订阅意林杂志的人可以不止一个):  events: {'意林': []}
 
 当我订阅意林,那么我就应该收入倒意林数组中,让意林知道我订阅了它: events: {'意林': ['我']} (这里’我’是执行函数)
 
 最后,当意林发布了新一期杂志时,那么我就会收到这一期杂志,也就是意林对数组中的’我’进行了执行。
 
 当我觉得意林不好看了,那我就会取消订阅,于是乎在意林数组中将我移除即可。
 
 如果我只想看下一期的意林,下下一期的意林我不想看了,那么我就进行单次订阅即可。(使用once方法)
 
下面这个`EventEmitter`类进行了简单实现,主要实现 'on'、'emit'、'once'和'remove'四个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
   |  class EventEmitter {      constructor() {     this.events = {}   }
       on(eventName, callback) {          if (!this.events[eventName]) {       this.events[eventName] = []     }          this.events[eventName].push(callback)          return this   }
       emit(eventName, ...args) {          if (!this.events[eventName]) {       return this     }          const fns = this.events[eventName]          fns.forEach(fn => fn.apply(this, args))          return this   }
       remove(eventName, callback) {     if (!this.events[eventName]) {       return this;     }          if (!callback) {       this.events[eventName] = null       return this     }          const index = this.events[eventName].indexOf(callback);     this.events[eventName].splice(index, 1);     return this;   }
       once(eventName, callback) {     const only = () => {       callback.apply(this, arguments);       this.remove(eventName, only);     };     this.on(eventName, only);     return this;   } }
 
  const emt = new EventEmitter()
  const listener1 = function (...args) {   console.log('意林的第一个订阅者', ...args); }
  const listener2 = function (...args) {   console.log('意林的第二个订阅者', ...args); }
  emt.on('yilin', listener1) emt.on('yilin', listener2)
 
  setTimeout(() => {   emt.remove('yilin', listener1) }, 500)
 
  setTimeout(() => {   emt.emit('yilin', 'hello world') }, 1000)
 
 
 
  | 
 
以上只是简单实现,如果有不正确的地方,还请各位大佬指正😀