发布订阅模式的js代码实现

发布订阅模式

复制class EventEmitter {
    constructor () {
        this.events = {};
    }
    // 绑定函数
    on (type, fn) {
        (this.events[type] || (this.events[type] = [])).push(fn);	
    }
    // 通知函数执行
    emit(type, ...args) {
        const callbackArr = this.events[type];
        if (!callbackArr || !callbackArr.length) {
            return;
        }
        callbackArr.forEach(callback => {
           callback(...args);
        });
        
    }
    // 解绑
    off (type, fn) {
        if (!this.events[type]) {
            return;
        }
        if (!fn) {
            this.events[type].length = 0;
            return;
        }
        const callbackArr = this.events[type];
        if (!callbackArr.length) {
            return;
        }
        
        let i = callbackArr.length,
            callback = null;
        while(i--) {
            callback = callbackArr[i];
            // fn是属性时对应once方法中的fn属性赋值
            if (callback === fn || callback.fn === fn) {
                callbackArr.splice(i, 1);
                break;
            }
        }
    }
    // 绑定的函数只会被调用一次
    once (type, fn) {
        const _this = this;
        function on (...args) {
            _this.off(type, on);
            fn.apply(_this, ...args);
        }
        // 给解绑时使用
        /* 当once绑定的函数一次也没有被调用过,但是fn函数需要被解绑时,
	解绑判断使用的就是包装函数on和绑定函数fn的比较结果,此时判定一定不正确。
	所以将fn保存起来供解绑时判定使用 */
        on.fn = fn;
        this.on(type, on);
    }
    
}

参考

发布订阅模式及用户TE_0915的评论

posted @   酉云良  阅读(201)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示