coleava / me

1 stars 0 forks source link

发布订阅模式 #7

Open coleava opened 3 years ago

coleava commented 3 years ago

发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。

发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。

let pubSub = {  // 控制中心
  list: {},

  // 订阅
  subscribe: function(key, fn) {
    if (!this.list[key]) this.list[key] = [];

    this.list[key].push(fn);
  },

  //取消订阅
  unsubscribe: function(key, fn) {
    let fnList = this.list[key];

    if (!fnList) return false;

    if (!fn) { // 不传入指定的方法,清空所用 key 下的订阅
      fnList && (fnList.length = 0);
    } else {
      fnList.forEach((item, index) => {
        item === fn && fnList.splice(index, 1);
      });
    }
  },

  // 发布
  publish: function(key, ...args) {
    for (let fn of this.list[key]) fn.call(this, ...args);
  }
}

// 订阅
pubSub.subscribe('onwork', time => {
  console.log(`上班了:${time}`);
})
pubSub.subscribe('offwork', time => {
  console.log(`下班了:${time}`);
})
pubSub.subscribe('launch', time => {
  console.log(`吃饭了:${time}`);
})

pubSub.subscribe('onwork', work => {
  console.log(`上班了:${work}`);
})

// 发布
pubSub.publish('offwork', '18:00:00');
pubSub.publish('launch', '12:00:00');

// 取消订阅
pubSub.unsubscribe('onwork');

DOM 的事件监听是“发布订阅模式”:

let loginBtn = document.getElementById('#loginBtn');

 监听回调函数(指定事件)
  function notifyClick() {
      console.log('我被点击了');
  }

  // 添加事件监听
  loginBtn.addEventListener('click', notifyClick);
  // 触发点击, 事件中心派发指定事件
  loginBtn.click();            

  // 取消事件监听
  loginBtn.removeEventListener('click', notifyClick);