事件总线EventBus

2021-12-13  本文已影响0人  欢西西西
// 使用一个对象来管理所有的事件和处理程序
// 优点:有效地降低消息发布者和订阅者之间的耦合度
function EventBus() {
    this._eventBus = {};
}
EventBus.prototype = {
    constructor: EventBus,
    isStrValid(str) {
        return str && Object.prototype.toString.call(str) === '[object String]';
    },
    // 监听
    $on(eventName, fn) {
        if (!this.isStrValid(eventName)) {
            console.error('请传入正确的事件名称');
            return;
        }
        let eventBus = this._eventBus,
            handlers = eventBus[eventName];
        if (!handlers) {
            eventBus[eventName] = [fn];
            return;
        }
        if (handlers.includes(fn)) {
            return;
        }
        handlers.push(fn);
    },
    // fn只执行一次
    $once(eventName, fn) {
        let that = this;
        let onceFn = function () {
            fn(...arguments);
            that.$off(eventName, onceFn);
        };
        this.$on(eventName, onceFn);
    },
    // 触发
    $fire(eventName, ...args) {
        if (!this.isStrValid(eventName)) {
            console.error('请传入正确的事件名称');
            return;
        }
        let arrHandler = this._eventBus[eventName];
        if (!arrHandler || !arrHandler.length) {
            return;
        }
        arrHandler.forEach(fn => {
            fn(...args);
        });
    },
    // 解绑
    $off(eventName, ...fns) {
        if (!arguments.length) {
            // 解绑所有事件
            this._eventBus = {};
            return;
        }
        if (!this.isStrValid(eventName)) {
            console.error('请传入正确的事件名称');
            return;
        }
        if (!fns.length) {
            // 解绑所有的eventName事件
            delete this._eventBus[eventName];
            return;
        }
        // 解绑fns
        let handlers = this._eventBus[eventName];
        this._eventBus[eventName] = handlers.filter(fn => !fns.includes(fn));
    },
};
上一篇 下一篇

猜你喜欢

热点阅读