自定义PubSub-js发布订阅

PubSub-js语法解析

PubSub-js的语法:

1. token subscribe(msgName, callback): 订阅消息, 并返回一个标识token
2. publish(msgName, data): 异步发布消息
3. publishSync(msgName, data): 同步发布消息
4. unsubscribe(flag): 根据flag取消订阅

例子

//引入pubsub-js库


浏览器输出结果


图解



自定义PubSub-js

模块名称:pub-sub.js

(function (window) {
  //定义一个PubSub对象
  const PubSub = {}

  //分析数据结构  (用来保存所有待处理的回调函数的容器)
  /*
    {
      '消息名1': {
        'token1': callback,
        'token2': callback
      },
      '消息名'2: {
        'token3': callback,
        'token4': callback
      },
      ......
    }
  */

  //创建容器
  let callbackContainer = {}

  // 创建一个用于辅助生成token的变量
  let id = 0

  // 实现功能
  //1. token subscribe(msgName, callback): 订阅消息, 并返回一个标识token
  PubSub.subscribe = function (msgName, callback) {

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

    // 如果小容器还没创建
    if (!callbacks) {
      // 创建一个小容器,并让callbackContainer[msgName]等于小容器
      callbacks = {}
      callbackContainer[msgName] = callbacks
    }

    // 创建一个token
    const token = `uid_${++id}`

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

    // 把token返回
    return token
  }

  //2. publish(msgName, data): 异步发布消息
  PubSub.publish = function (msgName, data) {
    setTimeout(() => {
      // 获取存放callback的小容器
      let callbacks = callbackContainer[msgName]
      // 如果小容器存在
      if (callbacks) {
        // 将callbackContainer[msgName]里的回调函数全部异步执行,并传递对应的消息名data
        Object.values(callbacks).forEach(callback => {

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

  //3. publishSync(msgName, data): 同步发布消息
  PubSub.publishSync = function (msgName, data) {
    // 获取存放callback的小容器
    let callbacks = callbackContainer[msgName]
    // 如果小容器存在
    if (callbacks) {
      // 将callbackContainer[msgName]里的回调函数全部同步执行,并传递对应的消息名和data
      Object.values(callbacks).forEach(callback => callback(msgName, data))
    }
  }

  /*
  4. unsubscribe(flag): 根据flag取消订阅
    1. flag没有指定: 取消所有
    2. flag是一个token值: 取消对应的一个回调
    3. flag是msgName: 取消对应的所有
  */
  PubSub.unsubscribe = function (flag) {
    if (flag === undefined) {
      // 如果没传递flag直接将所有消息清除
      callbackContainer = {}
    } else if (typeof flag === 'string' && flag.indexOf('uid_') === 0) {
      // 如果传递的是一个token
      Object.values(callbackContainer).forEach(callbacks => {
        delete callbacks[flag]
      })
    } else {
      delete callbackContainer[flag]
    }
  }

  window.PubSub = PubSub

})(window)

你可能感兴趣的:(自定义PubSub-js发布订阅)