Once Handling in EventEmitter
·
1 min read
EventEmitter Initial Version
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)
}
}
Testing
const eventEmitter=new EventEmitter()
const listener=(args)=>{
console.log(args);
}
eventEmitter.once('test',listener)
eventEmitter.off('test',listener)
eventEmitter.emit('test',{a:1})
When executing the above code, you’ll find that the test event was triggered once, but it should not execute because it was turned off. The solution is as follows.
Once Failure
...
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)
}
Final Thoughts
Read more source code