Once Handling in EventEmitter

Once Handling in EventEmitter

3月 18, 2025 · 1 分钟阅读时长 · 105 字 · -阅读 -评论

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

Alan H
Authors
开发者,数码产品爱好者,喜欢折腾,喜欢分享,喜欢开源