从东京奥运会看js设计模式之发布订阅模式

开篇废话:本篇文章介绍发布-订阅模式,想必很多人听说过有一种观察者模式,网上既有资料说这是两种不同的设计模式,也有说这是一种模式,我倾向于认同他们是同一种设计模式。不必过于纠结

开篇楔子:东京奥运会已经开幕有一段时间了,在本次奥运会上我国的奥运健儿们取得了非常不错的成绩,截止至目前(2021.08.05),我国取得了34金24银16铜,在上班时间也时刻关注着比赛详情,但对于打工人来说摸鱼看完整比赛可能做不到,但是偶尔刷新查看一下奥运奖牌榜的事没少干。然后我就在想要是谁能及时通知我奖牌数的变化就好了,假设csdn提供了奖牌数据,我点击关注订阅后,然后csdn实时给我推送最新的奖牌榜,这不就是一个订阅-发布模式吗

用代码实现发布-订阅模式,获取奥运奖牌数,主要有三步

  • 保存所有订阅信息, eventList
  • 提供订阅方法,将订阅事件保存到eventList中
  • 提供一个发布方法,将所有订阅的事件发布出去
class Emitter {
  constructor() {
    // 保存所有订阅的事件
    this.eventList = {};
  }
  // 订阅事件:事件名称,事件处理函数
  subscribe(eventName, fn) {
    if (!this.eventList[eventName]) {
      this.eventList[eventName] = [];
    }
    this.eventList[eventName].push(fn);
  }
  // 发布事件:事件名称,参数
  publish(eventName, ...args) {
    const fns = this.eventList[eventName];
    if (!fns || fns.length === 0) {
      return;
    }
    fns.forEach((fn) => {
      fn.apply(this, args);
    });
  }
}

以上就是一个简单的发布订阅模式的实现,写一段测试代码

const csdn = new Emitter();
csdn.subscribe("china-medal", function (medals) {
  console.log("中国奖牌数:", medals);
});

csdn.publish("china-medal", "34金24银16铜");
csdn.publish("china-medal", "43金30银27铜");

输出结果:

中国奖牌数: 34金24银16铜
中国奖牌数: 43金30银27铜

如果奥运会结束,我就不需要再关注奖牌数,这时需要一个取消订阅事件remove

class Emitter {
 // 省略其他代码xxx
  remove(eventName, fn) {
    const fns = this.eventList[eventName];
    if (!fns || fns.length === 0) {
      return;
    }
    const idx = fns.findIndex((item) => item === fn);
    fns.splice(idx, 1);
  }
}

继续来一段测试代码,测试能否正确取消订阅

const csdn = new Emitter();
const fn = function (medals) {
  console.log("中国奖牌数:", medals);
};
csdn.subscribe("china-medal", fn);

csdn.publish("china-medal", "34金24银16铜");
csdn.publish("china-medal", "43金30银27铜");

setTimeout(() => {
  csdn.remove("china-medal", fn);
  csdn.publish("china-medal", "奥运会结束啦,不能发布了");
}, 1000);

还不错,这个发布订阅功能已经比较齐全了。

如果想看更多有关发布订阅模式的应用,请看我以前的文章:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值