likes
comments
collection
share

手写一个全局事件总线?分享 1 段优质 JS 代码片段!

作者站长头像
站长
· 阅读数 40

本内容首发于工粽号:程序员大澈,每日分享一段优质代码片段,欢迎关注和投稿!

大家好,我是大澈!

本文约 900+  字,整篇阅读约需 1 分钟。

今天分享一段优质 JS 代码片段,实现了一个简单的事件总线(event bus)。

老规矩,先阅读代码片段并思考,再看代码解析再思考,最后评论区留下你的见解!

class EventBus {
  constructor() {
    this.events = {};
  }

  // 发布事件
  emit(eventName, data) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(callback => callback(data));
    }
  }

  // 订阅事件
  on(eventName, callback) {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(callback);
  }

  // 取消订阅
  off(eventName, callback) {
    if (this.events[eventName]) {
      this.events[eventName] = this.events[eventName].filter(cb => cb!== callback);
    }
  }
}

// 创建全局事件总线实例
const globalEventBus = new EventBus();

// 在需要的页面或组件中使用
Page({
  onLoad() {
    // 订阅事件
    globalEventBus.on('customEvent'(data) => {
      console.log(`Received data in page: ${data}`);
    });

    // 触发事件
    setTimeout(() => {
      globalEventBus.emit('customEvent''Hello from other part of the app');
    }, 2000);
  }
})

分享原因

这段代码展示了如何实现一个简单的事件总线,包含事件的发布 (emit)、订阅 (on) 和移除 (off) 机制。

事件总线可以有效解耦组件,便于实现模块之间的通信。

我在小程序项目中会用的更多点,一般用于 跨页面通信 或 跨组件通信 ,可以用它来传递一些对象、数组等复杂数据。

当然,如果项目较大,也可以直接去引用配置三方状态库,如:Mobx 等。

这里提供一个简化版本,便于理解其工作原理,应用时可自行补充完善!

代码解析

1. class Bus

在 EventBus 类的构造函数中,初始化了一个空的对象 events ,用于存储不同事件名称及其对应的回调函数列表。

2. emit(eventName, data)

emit 方法用于发布指定名称的事件。

首先检查该事件是否有注册的回调函数,如果有,则遍历执行每个回调函数,并将传递的数据 data 作为参数传递给回调函数。

3. on(eventName, callback)

on 方法用于订阅指定名称的事件。

如果该事件还没有对应的回调函数列表,就创建一个空的列表。然后将传入的回调函数添加到该列表中。

4. off(eventName, callback)

移除off 方法用于取消对指定事件的订阅。

如果该事件存在回调函数列表,通过 filter 方法过滤掉要取消订阅的回调函数。

转载自:https://juejin.cn/post/7398789000222883879
评论
请登录