简单实现发布订阅者模式

147 阅读1分钟
class EventHub {
    private cache: { [key: string]: Array<(data: unknown) => void> } = {};
    // 订阅
    on(eventName: string, fn: (data: unknown) => void) {
        // api on 把函数推进cache数组
        this.cache[eventName] = this.cache[eventName] || [];
        this.cache[eventName].push(fn);
    }
    // 发布
    emit(eventName: string, data?: unknown) {
        // emit 把cache里面的fn依次调用
        (this.cache[eventName] || []).forEach(fn => fn(data));
    }

    remove(eventName: string, fn: (data: unknown) => void) {
        // 删除cache中的事件fn
        let index = indexOf(this.cache[eventName], fn);
        if (index === -1) return;
        this.cache[eventName].splice(index, 1);
    }
}

function indexOf(arr, item) {
    if (arr === undefined) return -1;
    let index = -1;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === item) {
            index = i;
            break;
        }
    }
    return index;
}

export default EventHub;