JS设计模式:发布订阅模式

发布订阅模式

// 发布订阅模式
// 灵感来源于 DOM2级事件绑定
// 可以给元素的事件行为,绑定多个不同的方法[事件池机制]
// 当元素的事件行为触发时,会一次将事件池中的方法执行
// 
let eventBus = (function () {
    let pond = [];

    // 往事件池中添加事件
    const on = function on(type, func) {
        // 判断当前事件池中 对应type类型的事件是否存在
        !Array.isArray(pond[type]) ? pond[type] = [] : null;
        let ary = pond[type];
        // 如果func不是 function类型 不处理 这步操作放在通知事件池中事件执行的时候也可以
        // if (typeof func !== 'function') return;
        // 如果事件池中已经存在 不再重复添加
        if (ary.includes(func)) return;
        ary.push(func);
    }

    // 移除事件池中的某个事件
    const off = function off(type, func) {
        // 判断当前事件池中 对应type类型的事件是否存在
        if (!Array.isArray(pond[type])) throw new TypeError(`${type} 在自定义事件池中不存在!`);
        let ary = pond[type],
            i = 0,
            len = ary.length,
            item = null;
        for (; i < len; i++) {
            item = ary[i];
            // 如果当前项存在数组中  移除
            if (item === func) {
                // 使用ary.splice(ary[i],1) 存在数组塌陷问题
                // 所以将当前项赋值为null,在emit触发事件池中的事件执行时,将此项移除即可
                ary[i] = null;
                break;
            }
        }
    }

    // 通知事件池中的指定自定义事件类型的方法执行
    const emit = function emit(type, ...params) {
        // 判断当前事件池中 对应type类型的事件是否存在
        let ary = pond[type],
            i = 0,
            item = null;
        if (!Array.isArray(pond[type])) throw new TypeError(`${type} 在自定义事件池中不存在!`);
        for (; i < ary.length; i++) {
            item = ary[i];
            if (typeof item === 'function') {
                item(...params);
                continue;
            }
            // 事件池中不是函数类型的值都移除掉
            ary.splice(i, 1);
            i--;
        }
    }

    return {
        on,
        off,
        emit
    }
})()

let fn1 = (param) => console.log(1, param);
let fn2 = (param) => console.log(2, param);
// 使用方法
eventBus.on('A', fn1);
eventBus.on('A', fn2);
eventBus.on('B', fn1);
eventBus.on('B', fn2);
setTimeout(() => {
    eventBus.emit('A', 'AAAAAA');
    eventBus.emit('B', 'BBBBBB');
}, 2000);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值