自定義PubSub-js發(fā)布訂閱

PubSub-js語(yǔ)法解析

PubSub-js的語(yǔ)法:

1. token subscribe(msgName, callback): 訂閱消息, 并返回一個(gè)標(biāo)識(shí)token
2. publish(msgName, data): 異步發(fā)布消息
3. publishSync(msgName, data): 同步發(fā)布消息
4. unsubscribe(flag): 根據(jù)flag取消訂閱

例子

//引入pubsub-js庫(kù)
<script src="https://cdn.bootcss.com/pubsub-js/1.7.0/pubsub.js"></script>
<script>
  //訂閱消息
  PubSub.subscribe('add',function(msg, data){
    console.log('消息名:'+msg,'數(shù)據(jù):'+data)
  })

  //訂閱消息并獲取返回的token
  let token = PubSub.subscribe('add',function(msg, data){
    console.log('消息名:'+msg,'數(shù)據(jù):'+data)
  })

  //發(fā)布消息
  PubSub.publish('add','haha') //異步
  PubSub.publishSync('add','haha') //同步

  console.log('發(fā)布消息之后') //打印輸出測(cè)試
  
  //取消消息訂閱
  PubSub.unsubscribe(token)
</script>

瀏覽器輸出結(jié)果


圖解



自定義PubSub-js

模塊名稱:pub-sub.js

(function (window) {
  //定義一個(gè)PubSub對(duì)象
  const PubSub = {}

  //分析數(shù)據(jù)結(jié)構(gòu)  (用來(lái)保存所有待處理的回調(diào)函數(shù)的容器)
  /*
    {
      '消息名1': {
        'token1': callback,
        'token2': callback
      },
      '消息名'2: {
        'token3': callback,
        'token4': callback
      },
      ......
    }
  */

  //創(chuàng)建容器
  let callbackContainer = {}

  // 創(chuàng)建一個(gè)用于輔助生成token的變量
  let id = 0

  // 實(shí)現(xiàn)功能
  //1. token subscribe(msgName, callback): 訂閱消息, 并返回一個(gè)標(biāo)識(shí)token
  PubSub.subscribe = function (msgName, callback) {

    // 獲取存放callback的小容器
    let callbacks = callbackContainer[msgName]

    // 如果小容器還沒(méi)創(chuàng)建
    if (!callbacks) {
      // 創(chuàng)建一個(gè)小容器,并讓callbackContainer[msgName]等于小容器
      callbacks = {}
      callbackContainer[msgName] = callbacks
    }

    // 創(chuàng)建一個(gè)token
    const token = `uid_${++id}`

    // 將callback添加到小容器
    callbacks[token] = callback

    // 把token返回
    return token
  }

  //2. publish(msgName, data): 異步發(fā)布消息
  PubSub.publish = function (msgName, data) {
    setTimeout(() => {
      // 獲取存放callback的小容器
      let callbacks = callbackContainer[msgName]
      // 如果小容器存在
      if (callbacks) {
        // 將callbackContainer[msgName]里的回調(diào)函數(shù)全部異步執(zhí)行,并傳遞對(duì)應(yīng)的消息名data
        Object.values(callbacks).forEach(callback => {

          callback(msgName, data)
        })
      }
    })
  }

  //3. publishSync(msgName, data): 同步發(fā)布消息
  PubSub.publishSync = function (msgName, data) {
    // 獲取存放callback的小容器
    let callbacks = callbackContainer[msgName]
    // 如果小容器存在
    if (callbacks) {
      // 將callbackContainer[msgName]里的回調(diào)函數(shù)全部同步執(zhí)行,并傳遞對(duì)應(yīng)的消息名和data
      Object.values(callbacks).forEach(callback => callback(msgName, data))
    }
  }

  /*
  4. unsubscribe(flag): 根據(jù)flag取消訂閱
    1. flag沒(méi)有指定: 取消所有
    2. flag是一個(gè)token值: 取消對(duì)應(yīng)的一個(gè)回調(diào)
    3. flag是msgName: 取消對(duì)應(yīng)的所有
  */
  PubSub.unsubscribe = function (flag) {
    if (flag === undefined) {
      // 如果沒(méi)傳遞flag直接將所有消息清除
      callbackContainer = {}
    } else if (typeof flag === 'string' && flag.indexOf('uid_') === 0) {
      // 如果傳遞的是一個(gè)token
      Object.values(callbackContainer).forEach(callbacks => {
        delete callbacks[flag]
      })
    } else {
      delete callbackContainer[flag]
    }
  }

  window.PubSub = PubSub

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

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