如何理解js的發(fā)布-訂閱模式

發(fā)布-訂閱模式/觀察者模式

發(fā)布-訂閱模式也叫觀察者模式,這是一個一對多的關系,可以多個訂閱者訂閱同一個事件,當事件觸發(fā)時就會通知訂閱者去執(zhí)行訂閱時綁定的程序;

我舉個例子來解釋一下:

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酒店過來喝酒,這個過程就是發(fā)布事件

A.emit("結婚");

以下是我的實現(xiàn)過程:

class EventEmitter {
    constructor(){
        this._count=null;
        
    }
    //訂閱事件
    on(type,callBack,flag){
        //創(chuàng)建_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類型,則執(zhí)行newListener對應的函數(shù)
        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);
        
    }

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

    // 獲取當前type事件的數(shù)組對象
    listeners(type){
        return this._events[type]||[];
    }

    // 訂閱事件并在第一時間觸發(fā)
    prependListener(type,callBack){
        this.on(type,callBack,true);
    }
    
    // 訂閱一次性事件并在第一時間觸發(fā)
    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事件所有的執(zhí)行函數(shù)
    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;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 對于開發(fā)人員來說,設計模式有時候就是一道坎,但是設計模式又非常有用,過了這道坎,它可以讓你水平提高一個檔次。而在a...
    WANKUN閱讀 320評論 0 2
  • 1.實例演進 考慮實現(xiàn)如下功能,點擊一個按鈕后出現(xiàn)一個遮罩層。原始辦法:我們只需要實現(xiàn)一個創(chuàng)建遮罩層的函數(shù)并將其作...
    love丁酥酥閱讀 409評論 0 2
  • 本周目標回顧: 1.完成工作模塊測試,輸出測試報告 2.繼續(xù)細分工作目標(進行可行性分析) 3.最少3次晨跑 4....
    未灰閱讀 187評論 3 0
  • 朋友從小是乖乖女,聽媽媽的話,上學考試,工作,每一步都會聽從媽媽的安排,也終于如愿以償成為真正的事業(yè)編制。進入某宣...
    怡兒話書影閱讀 573評論 2 2

友情鏈接更多精彩內容