EventEmitter初版
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
| class EventEmitter{
constructor(){ this.events={} }
on(type,listener){ if(!this.events[type]){ this.events[type]=[] } this.events[type].push(listener) }
emit(type,...args){ this.events[type].forEach(listener=>{ listener.call(this,...args) }) }
off(type,listener){ if(this.events[type]){ const index=this.events[type].indexOf(listener) if(index!==-1){ this.events[type].splice(index,1) } } }
once(type,listener){ const onceListener=(...args)=>{ listener.call(this,...args) this.off(type,onceListener) } this.on(type,onceListener) } }
|
测试
1 2 3 4 5 6 7
| const eventEmitter=new EventEmitter() const listener=(args)=>{ console.log(args); } eventEmitter.once('test',listener) eventEmitter.off('test',listener) eventEmitter.emit('test',{a:1})
|
执行上述代码,会发现test事件被触发了一次,预期应该是不执行的,因为off了。解决办法如下。
once失效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| ... off(type,listener){ if(this.events[type]){ const index=this.events[type].findIndex(l=>l.fn===listener||l===listener) if(index!==-1){ this.events[type].splice(index,1) } } }
...
once(type,listener){ const onceListener=(...args)=>{ listener.call(this,...args) this.off(type,onceListener) } onceListener.fn=listener this.on(type,onceListener) }
|
写在最后
多看源码