事件的发布-订阅实现

学习笔记,简要记录一下。

适用场景

监听事件的位置和触发事件的位置不受限,可以用于任意组件间的通信。Vue 中的 EventBus 就是一个典型应用。

实现思路

  • 处理事件和监听函数的对应关系 —— 用对象(eventMap)存储事件和处理函数的映射关系
  • 实现事件订阅 —— 往 eventMap 写入事件处理函数
  • 实现事件发布 —— 从 eventMap 读取事件处理函数并依次执行

具体实现

class myEventEmitter {
  constructor() {
    this.eventMap = {};  // 存储事件和监听函数之间的关系
  }
  
  // type:事件名称; handler:事件处理函数
  on(type, handler) {
    // hanlder 必须是一个函数
    if (!(handler instanceof Function)) {
      throw new Error("hanler必须是函数");
    }
    // 判断 type 事件对应的队列是否存在
    if (!this.eventMap[type]) {
      // 若不存在,新建该队列
      this.eventMap[type] = [];
    }
    // 若存在,直接往队列里推入 handler
    this.eventMap[type].push(handler);
  }
  
  // type:事件名称; params:支持传参
  emit(type, params) {
    // 假设该事件是有订阅的(对应的事件队列存在)
    if (this.eventMap[type]) {
      // 将事件队列里的 handler 依次执行出队
      this.eventMap[type].forEach((handler, index) => {
        handler(params); // 别忘了读取 params
      });
    }
  }
  
  off(type, handler) {
    if (this.eventMap[type]) {
      this.eventMap[type].splice(this.eventMap[type].indexOf(handler) >>> 0, 1);
    }
  }
}

测试

// 实例化 myEventEmitter
const myEvent = new myEventEmitter();
// 编写一个简单的 handler
const testHandler = function (params) {
  console.log(`test事件被触发了,testHandler 接收到的入参是${params}`);
};
// 监听 test 事件
myEvent.on("test", testHandler);
// 在触发 test 事件的同时,传入希望 testHandler 感知的参数
myEvent.emit("test", "newState");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值