JS中的事件总线(秒懂事件总线概念)

一、事件总线概念

1.基本概念

事件总线(Event Bus)是一种在软件架构中用于组件间通信的模式。它允许不同组件在应用程序中解耦并相互通信,而不需要显式地引用彼此。事件总线的概念类似于实际生活中的公共交通系统,各个组件就像乘客一样,可以通过总线来进行通信。

2.核心概念

  1. 事件(Event):事件是系统中某种状态的变化或者动作的抽象表示,它可以是任何需要通知其他组件的动作或变化。比如,用户点击了某个按钮、数据加载完成、系统启动等都可以是事件。

  2. 事件发布者(Event Publisher):也称为事件发送者或者生产者,负责发出(发布)特定类型的事件。当某个组件的状态发生变化时,事件发布者就会生成相应的事件并将其发送到事件总线上。

  3. 事件订阅者(Event Subscriber):也称为事件消费者,订阅者会监听事件总线上特定类型的事件,并在事件发生时执行相应的操作。订阅者可以选择订阅它感兴趣的事件,而忽略其他事件。

  4. 事件总线(Event Bus):事件总线是事件发布者和事件订阅者之间的中介,它负责接收和分发事件。当事件发布者发布一个事件时,事件总线会将该事件传递给所有订阅了该事件类型的订阅者。

二、事件总线优点

  • 解耦性:事件总线可以帮助组件之间实现解耦,因为它们不需要直接引用彼此来通信,而是通过发布和订阅事件来进行通信。
  • 简化通信:组件之间的通信通过事件总线可以更加简单和直观。组件只需关注自己感兴趣的事件,而不需要了解其他组件的实现细节。
  • 扩展性:使用事件总线可以更容易地扩展应用程序,因为新的组件可以通过订阅现有的事件来集成到系统中,而不需要修改现有的代码。

三、事件总线常见模式

  1. 命令模式(Command Pattern)

    • 在命令模式中,事件总线负责接收和调度命令对象,这些命令对象封装了要执行的操作及其参数。
    • 订阅者订阅特定类型的命令,并在收到命令时执行相应的操作。
    • 该模式适用于需要对操作进行封装和延迟执行的情况,例如实现撤销/重做功能。
  2. 请求-响应模式(Request-Response Pattern)

    • 在请求-响应模式中,事件总线充当请求和响应之间的中介。
    • 发送请求的组件发布请求事件,而处理请求的组件监听并响应该事件。
    • 该模式适用于需要请求和响应之间有明确关联的情况,例如前端页面向后端服务发送请求并接收响应。
  3. 消息队列模式(Message Queue Pattern)

    • 在消息队列模式中,事件总线作为消息队列的一部分,用于在不同的组件之间传递消息。
    • 发送者将消息发布到队列,而接收者则监听队列以接收消息。
    • 该模式适用于需要异步处理消息、支持消息持久化和重试的情况,例如分布式系统中的任务调度和消息传递。
  4. 中介者模式(Mediator Pattern)

    • 在中介者模式中,事件总线充当中介,协调组件之间的通信,并封装组件之间的交互。
    • 组件不直接通信,而是通过事件总线进行通信,使得组件之间的耦合度降低。
    • 该模式适用于需要将复杂系统分解为多个独立的组件,并通过中介者来协调它们之间的交互的情况。

四、事件总线实例

1.事件总线-订阅模式

// 创建事件总线对象
const eventBus = {
  // 事件存储对象,键为事件名,值为订阅者数组
  events: {},

  // 订阅事件的方法
  subscribe: function(eventName, callback) {
    // 如果事件不存在,则初始化为一个空数组
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    // 将回调函数添加到事件订阅者数组中
    this.events[eventName].push(callback);
  },

  // 发布事件的方法
  publish: function(eventName, data) {
    // 如果事件不存在,则直接返回
    if (!this.events[eventName]) {
      return;
    }
    // 遍历事件订阅者数组,并依次调用回调函数
    this.events[eventName].forEach(callback => {
      callback(data);
    });
  }
};

// 示例:定义事件订阅者
function handleEvent1(data) {
  console.log('事件1已触发,数据为:', data);
}

function handleEvent2(data) {
  console.log('事件2已触发,数据为:', data);
}

// 示例:订阅事件
eventBus.subscribe('event1', handleEvent1);
eventBus.subscribe('event2', handleEvent2);

// 示例:发布事件
eventBus.publish('event1', { message: 'Hello from event 1!' });
eventBus.publish('event2', { message: 'Hello from event 2!' });

通过 subscribe 方法订阅事件,通过 publish 方法发布事件。当事件被发布时,事件总线会调用相应的订阅者函数,并传递相应的数据给它们。 

 2.命令模式

// 定义命令对象
class DrawCommand {
  constructor(shape, x, y) {
    this.shape = shape;
    this.x = x;
    this.y = y;
  }

  execute() {
    this.shape.draw(this.x, this.y);
  }
}

// 定义圆形类
class Circle {
  draw(x, y) {
    console.log(`绘制圆形,圆心坐标 (${x}, ${y})`);
  }
}

// 定义矩形类
class Rectangle {
  draw(x, y) {
    console.log(`绘制矩形,左上角坐标 (${x}, ${y})`);
  }
}

// 创建事件总线对象
const eventBus = {
  commands: [],

  // 接收命令并执行
  receiveCommand(command) {
    this.commands.push(command);
    this.executeCommands();
  },

  // 执行队列中的命令
  executeCommands() {
    while (this.commands.length > 0) {
      const command = this.commands.shift();
      command.execute();
    }
  }
};

// 示例:创建圆形和矩形对象
const circle = new Circle();
const rectangle = new Rectangle();

// 示例:模拟用户操作,发布绘制命令
eventBus.receiveCommand(new DrawCommand(circle, 100, 100));
eventBus.receiveCommand(new DrawCommand(rectangle, 200, 200));

在这个实例中,我们定义了两种形状(圆形和矩形)以及一个绘制命令对象 DrawCommand。当用户发布绘制命令时,事件总线接收并执行这些命令。这种方式下,命令的接收和执行被解耦,使得我们可以方便地添加新的命令和形状,而不需要修改原有的代码。

五、事件总线应用

事件总线在现代软件架构中有广泛的应用,特别是在大型、复杂的应用程序中。下面是一些事件总线的应用场景:

  1. 前端应用程序

    • 在前端开发中,事件总线常用于组件间通信。例如,Vue.js 框架中的 EventBus 可以用来在组件之间发送和接收事件,从而实现解耦和组件通信。
    • 在 React 应用中,可以使用 Context API 或第三方库来实现事件总线,以实现组件之间的通信和状态管理。
  2. 后端服务

    • 在微服务架构中,事件总线可以用于服务间的异步通信。例如,使用 Kafka 或 RabbitMQ 来作为事件总线,服务之间通过发布-订阅模式进行通信。
    • 在消息驱动的架构中,事件总线可以用来处理异步任务和事件处理。
  3. 分布式系统

    • 在分布式系统中,事件总线可以用来实现事件驱动架构,以处理分布式系统中的事件和消息。这有助于解耦不同部分之间的依赖关系,提高系统的可扩展性和灵活性。
  4. 日志和监控

    • 在日志记录和监控系统中,事件总线可以用来收集、处理和分发日志和监控数据。例如,使用 ELK(Elasticsearch、Logstash、Kibana)堆栈来建立一个事件总线,以收集和分析系统的日志和指标数据。
  5. 工作流程管理

    • 在工作流程管理系统中,事件总线可以用来处理和触发工作流程中的事件和任务。这有助于实现复杂的业务流程和自动化工作流程。
  6. 测试和模拟

    • 在测试和模拟环境中,事件总线可以用来模拟和触发事件,以测试系统的行为和性能。这有助于进行单元测试、集成测试和性能测试。

总的来说,事件总线是一种非常强大和灵活的架构模式,可以应用于各种不同的场景和应用领域,从而实现系统的解耦、可扩展和可维护性。

  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue3.x移除了事件总线概念,不再提供全局的事件总线对象。以前的版本,我们可以使用Vue实例的`$on`、`$emit`、`$off`和`$once`方法来实现事件的绑定、触发和解绑。但是在Vue3.x,这些方法已经从实例移除了。相反,Vue3.x推荐使用其他的事件管理库,比如mitt或者event bus。mitt是一个小巧且高效的事件管理库,可以帮助我们在组件之间进行事件的订阅、发布和取消订阅操作。你可以通过`npm install --save mitt`或者`yarn add mitt -S`安装mitt模块。另一种方式是使用event bus模式,通过创建一个全局的事件总线对象来实现组件之间的通信。你可以在主文件创建一个新的Vue实例,并将其作为事件总线对象导出,然后在其他组件导入并使用该事件总线对象来进行事件的订阅和触发。总之,Vue3.x移除了事件总线概念,但我们仍然可以使用其他的事件管理库或者自己创建一个全局的事件总线对象来实现类似的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vue3.0事件总线](https://blog.csdn.net/weixin_49666910/article/details/114252178)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [计算机程序设计语言课程设计(VUE.js)及实践项目的例子.txt](https://download.csdn.net/download/weixin_44609920/88236928)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值