<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      發布訂閱模式的TS實現

      簡介

      發布訂閱模式是一種常用的用于解耦的模式。

      它和觀察者模式的區別在于:

      • 觀察者模式:被觀察者需要維護一個觀察者的集合;
      • 發布訂閱模式:通信雙方互相不知道對方的存在,通過第三方事件總線進行通信。

      發布訂閱模式在前端領域很常見,例如:

      • Vue 框架中組件的$on$emit方法;
      • Node.js 中 EventEmitter 中的 onemit 方法。

      圖示

      1. 訂閱者通過on方法注冊事件:

        image-20240817114351978

      2. 發布者通過emit觸發回調列表:

        image-20240817114550701

        發布者和訂閱者雙方不知道各自的存在,它們僅通過Event Bus進行通信。

      實現

      事件總線最基本的兩個方法是 onemit

      常見的設計還有兩個方法是 offonceoff 用于注銷事件,onceon 的特例,表示僅訂閱一次。

      函數簽名

      type CallbackFn = (...args: any[]) => void;
      
      on(eventName: string, callback: CallbackFn): void;
      emit(enentName: string, ...args: any): void;
      off(eventName: string, callback: CallbackFn): void;
      once(eventName: string, callback: CallbackFn): void;
      

      實現思路

      在事件總線中需要建立起事件名回調集合的映射:

      • on時,將回調添加到指定事件名的回調集合中;
      • emit時,遍歷指定時間名的回調集合,依次執行其中的回調函數;

      回調集合可以使用Set實現,也可以使用數組實現。

      由于on的實現需要做去重,建議使用Set,比較方便。

      once的實現:

      once 可以基于 on 和 off 實現,先使用 on 注冊,執行回調之后就執行 off 注銷,從而實現僅觸發一次。

      代碼

      使用 TypeScript 實現。

      首先聲明一個回調函數的類型,簡化后續代碼:

      type CallbackFn = (...args: any[]) => void;
      

      然后是聲明 EventBus 類,成員屬性中使用對象建立起 “事件名與回調集合” 的映射關系:

      class EventBus{
          events: Record<string, Set<CallbackFn>> = {};
      
          constructor(){}
      	
          on(eventName: string, callback: CallbackFn){ /* ... */ }
          emit(eventName: string, ...args: any[]){/* ... */}
          off(eventName: string, callback: CallbackFn){/* ... */}
          once(eventName: string, callback: CallbackFn){/* ... */}
      }
      

      on

      on(eventName: string, callback: CallbackFn){
          if(!this.events[eventName]){
              this.events[eventName] = new Set();
          }
          this.events[eventName].add(callback);
      }
      
      • 如果事件名不存在,則要初始化創建一個 Set 用于記錄。
      • 如果事件名存在,則直接將回調添加到 Set 中。

      這段代碼可以通過 短路運算符 簡化:

      on(eventName: string, callback: CallbackFn){
          (this.events[eventName] ??= new Set()).add(callback);
      }
      

      emit

      遍歷回調集合就??了。(記得帶上函數參數)

      emit(eventName: string, ...args: any[]){
          this.events[eventName]?.forEach(cb => cb(...args));
      }
      

      off

      注銷事件也很簡單,使用 Set 的 delete 方法就可以了。

      off(eventName: string, callback: CallbackFn){
          this.events[eventName]?.delete(callback);
      }
      

      once

      對 once 傳入的回調函數做一層包裝,在執行之后調用 off 注銷事件。

      使用箭頭函數是為了 this 指向正確。使用 function 和 bind 也??,箭頭函數比較簡潔。

      once(eventName: string, callback: CallbackFn){
          const handler = (...args: any[]) => {
              callback(...args);
              this.off(eventName, handler);
          }
      
          this.on(eventName, handler);
      }
      

      代碼匯總

      type CallbackFn = (...args: any[]) => void;
      
      class EventBus{
        events: Record<string, Set<CallbackFn>> = {};
      
        constructor(){}
      
        on(eventName: string, callback: CallbackFn){
          (this.events[eventName] ??= new Set()).add(callback);
        }
      
        emit(eventName: string, ...args: any[]){
          this.events[eventName]?.forEach(cb => cb(...args));
        }
      
        off(eventName: string, callback: CallbackFn){
          this.events[eventName]?.delete(callback);
        }
      
        once(eventName: string, callback: CallbackFn){
          const handler = (...args: any[]) => {
            callback(...args);
            this.off(eventName, handler);
          }
      
          this.on(eventName, handler);
        }
      }
      
      posted @ 2024-08-17 12:35  feixianxing  閱讀(103)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 99国产精品一区二区蜜臀| 国产农村妇女毛片精品久久| 文山县| 国产午夜精品视频在线播放| 中国CHINA体内裑精亚洲日本| 2020国产欧洲精品网站| 免费现黄频在线观看国产| 亚洲中文无码av永久不收费| 中文字幕乱妇无码AV在线| 亚洲精品一区二区天堂| 天天摸天天做天天爽水多| 中文字幕久无码免费久久| 日韩av一区二区精品不卡| 漂亮的人妻不敢呻吟被中出| 国产婷婷综合在线视频中文| 国产毛片子一区二区三区| 国产999精品2卡3卡4卡| 桓台县| 国产精品无码无卡在线播放| 综合偷自拍亚洲乱中文字幕| 中文精品无码中文字幕无码专区| 日韩午夜福利片段在线观看| 精品少妇爆乳无码aⅴ区| 亚洲av成人一区国产精品| 亚洲人成小说网站色在线| 精品无码成人片一区二区| 九九综合va免费看| 男人进女人下部全黄大色视频| 亚洲AV日韩AV永久无码下载| 亚洲中文字幕伊人久久无码| 精品无码一区在线观看| 亚洲一区二区三区18禁| 国产精品久久久久久久专区| 精品一区二区无码免费| a级国产乱理伦片在线观看al| 国产日产亚洲系列最新| 吉川爱美一区二区三区视频| 欧美日韩精品一区二区三区高清视频 | 国产精品户外野外| 五月婷婷深开心五月天| 亚洲成人av在线系列|