发布-订阅模式的 JS 实现

文章介绍了发布-订阅模式的基本原理,通过创建一个EventCenter对象,实现了订阅、发布和取消订阅功能。此外,还支持一次性订阅,即事件触发后自动取消订阅。示例代码展示了如何使用这个简单的事件中心进行事件处理。
摘要由CSDN通过智能技术生成

前言

  • 发布-订阅是一种消息范式,通过定义发布者、订阅者、调度中心来完成消息通信。这是前端常用的消息通讯模式。
  • 事件由调度中心统一管理,由订阅者在调度中心订阅(注册)事件,发布者通过调度中心发布(触发)事件,订阅者通过事件收到消息,以达到消息通信。

实现

      function EventCenter() {
        this.events = {};
      }

      // 订阅
      EventCenter.prototype.on = function (eventName, callback) {
        if (!this.events[eventName]) {
          // 对不存在的订阅进行初始化
          this.events[eventName] = [callback];
        } else {
          // 对存在的订阅,继续加入副作用,一个订阅事件可以有多个副作用
          this.events[eventName].push(callback);
        }
      };

      // 发布
      EventCenter.prototype.trigger = function (eventName) {
        if (this.events[eventName]) {
          // 对当前存在的订阅,进行发布,处理所有的副作用
          this.events[eventName].forEach((cb) => cb());
        }
      };

      // 取消订阅
      EventCenter.prototype.off = function (eventName, callback) {
        if (this.events[eventName]) {
          const index = this.events[eventName].findIndex(
            (cb) => cb === callback
          );
          if (index !== -1) {
            this.events[eventName].splice(index, 1);
          }
          if (this.events[eventName].length === 0 || !callback) {
            delete this.events[eventName];
          }
        }
      };

      // 订阅和发布只进行一次
      EventCenter.prototype.once = function (eventName, callback) {
        const that = this; // 保留本作用域 this
        // once 调用其实就是重写callback,调用完真实的 callback 之后,off() 即可
        const fn = function () {
          callback();
          that.off(eventName, fn); // fn 里面的的 this 是 fn 本身的,故使用上面 that 才可调用 off()
        };
        this.on(eventName, fn); // 这里用 this 或者 that 没有区别
      };

      // 实例化构造函数
      const event = new EventCenter();

      const run = function () {
        console.log("running: 订阅发布成功");
      };
      const jump = function () {
        console.log("jumping: 订阅发布成功");
      };
      const fly = function () {
        console.log("flying: 订阅发布成功");
      };

      event.on("running", run);
      event.on("jumping", jump);
      event.once("flying", fly);

      event.off("jumping", jump); // 移除 jumping;
      event.trigger("jumping");   // jumping 无法发布;
      event.trigger("running");   // 触发 running,可以执行;
      event.trigger("running");   // 再次触发 running,可以继续执行;
      event.trigger("flying");    // 触发 flying,只执行一次,再次将不再执行;
      event.trigger("flying");    // 再次触发 flying 将不再执行;

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值