05 事件总线

59 阅读1分钟

事件总线的实现原理就是使用了发布-订阅模式

class EventBus {
    private static _instance = new EventBus();
    private eventMap: { [prop: string]: Array<() => any> } = {};
    
    constructor() {
        return EventBus._instance;
    }

    // 订阅
    subscribe(event, cb: () => any) {
        if (this.eventMap[event]) {
            if (this.eventMap[event].includes(cb)) return;
            this.eventMap[event].push(cb);
        } else {
            this.eventMap[event] = [cb];
        }
    }

    // 取消订阅
    unsubscribe(event, cb: () => any) {
        if (!this.eventMap[event]) return;
        const index = this.eventMap[event].findIndex((v) => v === cb);
        if (index > -1) this.eventMap[event].splice(index, 1);
    }

    // 仅仅订阅一次
    once(event, cb) {
        const callback = (...args) => {
            cb.apply(null, args);
            this.unsubscribe(event, callback);
        };
        this.subscribe(event, callback);
    }

    // 发布
    publish(event, ...args) {
        const cbs = this.eventMap[event];
        if (cbs?.length) {
            for (let i = 0; i < cbs.length; i++) {
                cbs[i].apply(null, args);
            }
        }
    }
}