SOURCE

class EmitEvent {
    constructor() {
        this.handlers = {}
    }

    emit(eventName, ...args){
         if (!this.handlers[eventName]) {
            return;
        }

        // 对事件队列进行浅拷贝,因为这个队列里可能会有once监听,他们执行完便会从队列中删除,会影响队列顺序
        const eventQueue = this.handlers[eventName].slice(0);
        eventQueue.forEach(fn => {
            fn(...args)
        })    
    }

    on(eventName, fn){
        const eventQueue = this.handlers[eventName]

        if (eventQueue) {
            eventQueue.push(fn);
        } else {
            this.handlers[eventName] = [fn];
        }
    }

    off(eventName, fn){
        const eventQueue = this.handlers[eventName];

        if (!eventQueue) {
            return;
        }

        const fnIndex = eventQueue.indexOf(fn);

        if (fnIndex > -1) {
            eventQueue.splice(fnIndex, 1);
        }
    }

    once(eventName, fn){
        const warpFn = (...args) => {
            fn(...args);
            this.off(eventName, warpFn);
        }
        this.on(eventName, warpFn)
    }
}

const test = (a) => console.log(a);

const eventInstance = new EmitEvent();

eventInstance.on('test', test);

eventInstance.once('test', test);

eventInstance.emit('test', 4455);

console.log('------');

eventInstance.emit('test', 4455);

// eventInstance.off('test', test);

// eventInstance.emit('test', 4455);
console 命令行工具 X clear

                    
>
console