事件总线--EvenBus

什么是事件总线

事件总线是实现基于事件驱动模式的方式之一,事件发送者将事件消息发送到一个事件总线上,事件订阅者向事件总线订阅和接收事件,然后再处理接收到的事件。当然,订阅者不仅可以接收和消费事件,它们本身也可以创建事件,并将它们发送到事件总线上。

事件总线是对发布-订阅模式的一种实现。它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的。

实现

我们如果想要实现一个自定义的EventBus,那么首先就需要明白需要实现什么功能:

  1. on(eventKey, callback):新增事件监听器,可以一个eventKey绑定多个callback,使用emit来触发指定eventKey的所有callback
  2. once(eventKey, callback):监听一个自定义事件,但是只会执行一次,执行完毕后当前事件监听器会被移除
  3. off([eventKey, callback]):参数eventKey和callback都是可选的,
  • 如果没有提供参数,则移除所有的事件监听器
  • 如果只提供了eventKey,则移除该事件所有的监听器
  • 如果同时提供了eventKey和callback,则只移除这个回调的监听器
  1. emit(eventKey, […args]):触发指定的事件,附加参数都会传给监听器回调。如果执行的是once定义的监听器,则执行后将会移除该监听器

具体实现

  • on和once是用来注册函数的,并将其保存到数组中,因为要维持插入顺序和执行顺序一致
  • emit根据key值找到存放回调函数的数组,并执行数组里面的所有函数,可以传入额外的参数
  • off则根据传入的参数,也可能不传参数,找到函数并删除
class EventBus {
     constructor() {
         this.events = {}; // 初始值为空对象
     }
     //订阅事件
     on(eventKey, fn, isOnce = false) {
         const events = this.events; // 引用赋值
         if (events[eventKey] == null) {
             events[eventKey] = []; // 初始化eventKey对应的fn数组
         }
         // 将函数添加到数组中
         events[eventKey].push({fn,isOnce});
     }
     //订阅事件,只会执行一次
     once(eventKey, fn) {
         // 代码复用
         this.on(eventKey, fn, true);
     }
     //取消订阅
     off(eventKey, fn) {
         // 如果传入了函数,但是未指定eveneky,直接不执行
         if (!eventKey && fn) return;
         if (!eventKey && !fn) {
             // 如果未传入参数,则清除所有绑定的函数
             this.events = {};
         } else if (eventKey && !fn) {
             // 解绑当前eventKey对应的函数
             this.events[eventKey] = [];
         } else {
             // 解绑eventKey和fn对应的函数
             if (this.events[eventKey]) {
                 this.events[eventKey] = this.events[eventKey].filter(item => item.fn !== fn);
             }
         }
     }
     //发布事件
     emit(eventKey, ...args) {
         const fnList = this.events[eventKey]; // 引用赋值
         if (fnList == null) return;
         this.events[eventKey] = fnList.filter(item => {
             const {fn,isOnce} = item;
             fn(...args); // 执行函数,并传入额外参数
             if (!isOnce) return true; // 如果不是once,表示后续还可以继续被执行
             return false; // 如果是once,表示执行一次后就要被过滤掉
         })
     }
 }

参考博客:
小猪课堂
诸葛小愚

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值