• <dd id="ac5t4"><track id="ac5t4"></track></dd><rp id="ac5t4"></rp>
    <th id="ac5t4"><track id="ac5t4"></track></th>

      <progress id="ac5t4"></progress>

      <li id="ac5t4"><object id="ac5t4"></object></li>
      帶你輕松搞定觀察者模式和發布訂閱模式的區別

      發布日期: 2022-05-07

      瀏覽量: 3115

      01、模式的概念

      熟悉Vue的小伙伴都知道,在Vue中使用“觀察者模式”去通知視圖更新,使用“發布訂閱”$on,$emit來實現自定義事件,所以搞清楚兩者之間的關系很重要啦!

      02、觀察者模式

      一個對象(觀察者)訂閱另一個對象(主題),當主題被激活的時候,觸發觀察者里面的事件。

      舉個例子:打點滴時,我們會觀察吊瓶的變化,當快打完時,就要通知護士來取針。這里護士/我們就是觀察者(Obeserver),吊瓶就是被觀察者/主題。

        class Subject { //被觀察者數據--吊瓶

          constructor(name="蛋糕老師"){

          this.state = 100;

          this.name = name;

          this.obs = [] //會有多個觀察者

          }

            addObs(ob){

              this.obs.push(ob)

                }

        setState(state){ //改變狀態的方法

          this.state = state

          //要去通知觀察者去做動作 -- 拔針 

          this.obs.forEach((ob)=>{

            ob.update(this) //讓觀察者去做更新

              })

            }

      }

        class Obeserver{ //觀察者 -- 醫生

          constructor(name){

          this.name = name;

        //在觀察者里面是否可以記錄/觀察了哪些數據

               }

          update(subject){

          //醫生也有可能觀察多個打針的人 

          if (!subject.state) {

              console.log(`${this.name} 收到通知         :${subject.name} 的 帶瓶打完啦!`)

              }else {

          console.log(` ${this.name} 收到通知 :${subject.name} 的帶瓶量: ${subject.state}!`)

                     }

               }

           }

           var zhiliao = new Subject();

           var hushi = new Obeserver("護士");

           var yisheng = new Obeserver("醫生")

           zhiliao.addObs(hushi) 

           zhiliao.addObs(yisheng)

           zhiliao.setState(50) 

      03、發布訂閱

      訂閱者把自己想要訂閱的事件注冊到調度中心,當發布者發布事件到調度中心(就是該事件被觸發),再由調度中心統一調度訂閱者注冊到調度中心的處理代碼。

      其實簡單理解就是我們的自定義事件,比如在Vue中,Vue實例($bus)就是統一的調用中心,我們使用$bus去$on一個自定義事件myEvent就是發布者發布一個事件到調度中心,然后在其他地方$bus.$emit(myEvent)一下就相當于事件被觸發,然后$bus就去執行對應事件的回調函數 。var Event = {

          _listeners: {},    

          // 添加

          $on: function(type, fn) {

      if (typeof this._listeners[type] === "undefined") {

        this._listeners[type] = [];

              }

          if (typeof fn === "function") {

            this._listeners[type].push(fn);

            }    

           return this;

          },

          // 觸發

        $emit: function(type) {

          var arrayEvent = this._listeners[type];

          if (arrayEvent instanceof Array) {

            for (var i=0, length=arrayEvent.length; i

              if (typeof arrayEvent[i] === "function") {

                arrayEvent[i]({ type: type });    

                      }

                  }

              }    

              return this;

          },

          // 刪除

        $off: function(type, fn) {

          var arrayEvent = this._listeners[type];

          if (typeof type === "string" && arrayEvent instanceof Array) {

            if (typeof fn === "function") {

            for (var i=0, length=arrayEvent.length;i+=1){

            if (arrayEvent[i] === fn){

              this._listeners[type].splice(i, 1);

              break;

               }

               }

            } else {

              delete this._listeners[type];

                  }

              }

              return this;

          }

      };

      04、總結

      學習這兩種模式,其實就是為了代碼解耦 ,讓每個獨立的對象分開。需要從日常的業務場景去觀察,比如在分頁插件中,就可以利用“發布訂閱”為點擊每一個分頁數的時候觸發($emit)一個自定義事件,如果需要在點擊分頁的是做一些其他的時候,就可以在外面$on 這個事件,那么分頁插件就可以很好的封裝起來,不用給里面傳遞參數或者回調函數之類的了。


      關注我們
      值得信賴的IT教育機構

      值得信賴的IT培訓機構

      成都校區地址:成都市武侯區孵化園9號樓A座2樓 西安校區地址:西安市未央區鳳城九路海博廣場B座 深圳校區地址:深圳市福田區彩田南路深圳青年大廈

      蓉華教育,行勝于言,IT培訓學??诒x擇

      2016-2024 版權所有 ? 成都蓉華軟創科技有限公司官網(蜀ICP備20007585號-1 )

      微信咨詢

      微信咨詢

      聯系電話

      聯系方式

      173-5852-6576