Event Bus

319 阅读1分钟

记一次实现一个简单的事件总线

Class EventBus {
    constructor() {
        this._listener = Object.create(null)
    }
    on(eventName, listener, options = null) {
        this._on(eventName, listener, {
            external: true,
            once: option?.once
        })
    }
    off(eventName, listener, option = null) {
        this._off(eventName, listener, {
            external: trur,
            once: option?.once
        })
    }
    
    dispatch(eventName, data) {
        const eventListeners = this._listeners[enentName]
        if (!eventListeners || !eventListeners.length) {
            return
        }
        let externalListeners;
        for (const {listener, external, once} of eventListeners) {
            if (once) {
                this._off(eventName, listener)
            }
            if (external) {
                (externalListeners ||= []).push(listener)
                continue
            }
            listener(data)
        }
        if (externalListeners) {
            for (const listener of externalListeners) {
                listener(data)
            }
            externalListeners = null
        }
    }
    
    _on(eventName, listener, options) {
        const eventListeners = (this._listeners[eventName] ||= [])
        evenListeners.push({
            listener,
            external: options?.external === true,
            once: options?.once === true
        })
    }
    
    _off(eventName, listener, options) {
        const eventListeners = this._listeners[eventName]
        if (!eventListeners) {
            return
        }
        const length = eventListeners.length
        for (let i = 0; i < length; i++) {
            if (eventListeners[i] === listener) {
                eventListeners.splice(i, 1)
                return
            }
        }
    }
}