美文网首页
发布订阅模式

发布订阅模式

作者: 小枫学幽默 | 来源:发表于2020-06-25 12:02 被阅读0次
class EventEmit {
  constructor() {
    //记录所有的事件回调
    //数据结构
    /* hungry 为事件名字
    {
        hungry:[
          callback1,
          callback2,
          ...
        ],
        love:[
          callback1,
          callback2,
          ...
        ]
    }
    */
    this.callbacks = {};
  }

  /**
   * 订阅方法 用来注册事件订阅
   * @params eventName 要订阅的事件
   * @params callback 该事件发生时的回调函数
   * */
  $on(eventName, callback) {
    //拿到事件名字和事件回调之后 存储进数组
    this.callbacks[eventName] = this.callbacks[eventName] || [];
    this.callbacks[eventName].push(callback);
  }

  /**
   * 发布(广播事件)方法 用来触发事件
   * @params eventName 要触发的事件
   * @params eventParams 触发事件时的参数
   * */
  $emit(eventName, eventParams = "") {
    //若该事件无人订阅 则不处罚回调
    if (!this.callbacks[eventName]) return;
    //若事件有人订阅,则挨个执行订阅时回调函数
    this.callbacks[eventName].forEach((callback) => {
      callback(eventParams);
    });
  }
  /**
   * 移除事件订阅
   * @params eventName 要移除的事件的名字
   * @params callback 要移除事件的回调函数
   * */
  $remove(eventName, callback) {
    if (this.callbacks[eventName]) {
      this.callbacks[eventName] = this.callbacks[eventName].filter(
        (cb) => cb != callback
      );
    }
  }

  /**
   * 订阅方法 用来注册事件订阅
   * @params eventName 要订阅的事件
   * @params callback 该事件发生时的回调函数
   * */
  $once(eventName, callback) {
    let fn = (eventParams = "") => {
      callback(eventParams);
      //执行一次之后删除该事件订阅
      this.$remove(eventName, fn);
    };
    this.$on(eventName, fn);
  }
}

let eventBus = new EventEmit();

console.log("== 订阅 ==");

eventBus.$on("hungry", function (name) {
  console.log(`${name} => 饿了`);
});

eventBus.$once("once", function (msg) {
  console.log(`once 被触发了`);
  console.log(msg);
});

eventBus.$on("hungry", function (name) {
  console.log(`${name} => 饿了去吃饭啊`);
});

eventBus.$on("love", function (name) {
  console.log(`${name} => I love you too !`);
});

function drinkWater(){
    console.log(`喝了点水`);    
}
eventBus.$on("hungry", drinkWater);

eventBus.$emit("hungry", "BayMax");

eventBus.$emit("love", "BayMax");

eventBus.$remove("hungry", drinkWater);
console.log("== 移除事件订阅之后再次触发==");
eventBus.$emit("hungry", "BayMax");
console.log("== 触发once ==");
eventBus.$emit("once", "第一次触发");
eventBus.$emit("once", "第二次触发");

相关文章

网友评论

      本文标题:发布订阅模式

      本文链接:https://www.haomeiwen.com/subject/rmlsfktx.html