如何理解js的发布-订阅模式

发布-订阅模式/观察者模式

发布-订阅模式也叫观察者模式,这是一个一对多的关系,可以多个订阅者订阅同一个事件,当事件触发时就会通知订阅者去执行订阅时绑定的程序;

我举个例子来解释一下:

A同学想在结婚的时候邀请好友B、C、D、E、F、G...来喝喜酒,这个邀请的名单其实就是订阅事件

class Person extends EventEmitter{
    constructor(){
        super();
        
    }
}

let A= new Person();

function drinkFn(){
    console.log( `xxxx年xx月xx日来xx大酒店和我的喜酒!`)
}
A.on("结婚",drinkFn);

等到A同学要结婚的时候,他就会去通知他的好友XXX时间XX酒店过来喝酒,这个过程就是发布事件

A.emit("结婚");

以下是我的实现过程:

class EventEmitter {
    constructor(){
        this._count=null;
        
    }
    //订阅事件
    on(type,callBack,flag){
        //创建_events对象
        if(!this._events){
            this._events=Object.create(null);
        }
        
        // 判断_events对象是否有type属性
        if(this._events[type]){
            if(flag){
                this._events[type].unshift(callBack)
            }else{
                this._events[type].push(callBack)
            }
            
        }else{
            this._events[type]=[callBack]
        }
        
        //type如果不是newListener类型,则执行newListener对应的函数
        if(type!=="newListener"){
            this._events["newListener"]&&this._events["newListener"].forEach(fn=>{
                fn(type,callBack);
            })
        }
        // 超出最大绑定事件限制提示
        if(this._events[type].length>=this.getMaxListeners()){
            console.log("超出最大绑定事件限制")
        }
    }

    //订阅一次性事件
    once(type,callBack,flag){
        function warp(...argments){
            callBack(...argments);
            this.removeListener(type,callBack)
        }
        warp.cb=callBack;
        this.on(type,warp,flag);
        
    }

    //发布事件
    emit(type,...args){
        if(this._events[type]){
            this._events[type].forEach(fn => {
                fn.call(this,...args)
            });
        }
    }

    // 获取当前type事件的数组对象
    listeners(type){
        return this._events[type]||[];
    }

    // 订阅事件并在第一时间触发
    prependListener(type,callBack){
        this.on(type,callBack,true);
    }
    
    // 订阅一次性事件并在第一时间触发
    prependOnceListener(type,callBack){
        this.once(type,callBack,true);
    }
    
    // 获取当前实例所有的事件类型
    eventNames(){
        return Object.keys(this._events)
    }
    
    // 获取当前type事件类型的长度
    listenerCount(type){
        if(this._events[type]){
            return this._events[type].length
        }else{
            return 0
        }
        
    }
    
    // 移除type事件所有的执行函数
    removeListener(type,callBack){
        if(this._events[type]){
            this._events[type]=this._events[type].filter(fn=>{
                return callBack!=fn&&fn.cb!=callBack
            })
        }
    }
    
    // 移除实例上所有的事件
    removeAllListeners(){
        this._events=Object.create(null)
    }

    // 获取当前实例的最大事件绑定限制
    getMaxListeners(){
        return this._count ? this._count :EventEmitter.defaultMaxListeners;
    }
    
    // 设置当前实例的最大事件绑定限制
    setMaxListeners(n){
        this._count=n;
    }
        
}
// 设置默认的最大事件绑定限制
EventEmitter.defaultMaxListeners=10;

module.exports=EventEmitter;

你可能感兴趣的:(如何理解js的发布-订阅模式)