設計模式:訂閱-發(fā)布模式以及Vue 中的 $on,$emit 的簡易實現(xiàn)

什么是“訂閱-發(fā)布模式”?

訂閱-發(fā)布模式定義了對象之間的一種一對多的依賴關(guān)系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴它的對象都可以得到通知。

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

訂閱-發(fā)布模式和觀察者模式概念相似,但在訂閱-發(fā)布模式中,訂閱者和發(fā)布者之間多了一層中間件:一個被抽象出來的信息調(diào)度中心。

http://www.itdecent.cn/p/89d656db6548

代碼實現(xiàn)

class Dep{
     
    constructor(){
        this.depsList=[];
    }
    /**
     * 訂閱
     * @param {*} key 事件
     * @param {*} component 組件
     * @param {*} fn 回調(diào)
     */

    on(key,component,fn){
       
        if(typeof component!='object' || component===null)
        {
            throw TypeError('component 不合法');
        }
        let index=this.depsList.findIndex(item=>item.key===key);
        if(index>=0)
        {
            this.depsList[index].callbacks.set(component,fn);
        }
        else{
            var callbacks=new Map();
            callbacks.set(component,fn);
            this.depsList.push({key:key,callbacks:callbacks});

        }

    }
    /**
     * 發(fā)布
     * @param {}} key 
     * @param  {...any} props 
     */
    emit(key,...props){
        //debugger
         let deps=this.depsList.find(item=>item.key===key);
         if(!deps) return;
        
         for (let  [component,fn] of (deps.callbacks)) {
              fn.call(component,...props)
         
         }
    }
    /**
     * 取消訂閱
     * @param {*} key 
     * @param {*} component 
     */
     remove(key,component){
         if(typeof component==='object' && component!=null)
         {
            let deps=this.depsList.find(item=>item.key===key);
            if(!deps) return;
            if(deps.callbacks.has(component))
            {
                deps.callbacks.delete(component);
            }
                 
         }
         else{

            let index=this.depsList.findIndex(item=>item.key===key);
            if(index!=-1)
            {
                this.depsList.splice(index,1)
            }
         }
     }
}

let dep=new Dep();

class A {

}
class B {

}
let a=new A();
let b=new B();
//A 組件訂閱
dep.on('click',a,(...props)=>{
      
    console.log(`a 組件收到:${{...props}}`);
       
})

//B 組件訂閱

dep.on('click',b,(...props)=>{
      
    console.log(`b 組件收到:${{...props}}`);
       
})
//發(fā)布時間
dep.emit('click',a,b);
//移除A 組件上的訂閱
dep.remove('click',a);
//全部移除
dep.remove('click');

執(zhí)行結(jié)果

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容