Event Bus 使用心得

本文简要介绍了EventBus的工作原理,通过与广播的类比,详细解析了EventBus的使用流程,包括发送消息、注册事件及处理消息的具体实现。

之前一直没用过EventBus,新接手的项目里有这块代码,就看了一下。

现总结如下

原理和广播一样

1: 发送消息

EventBus.getDefault().post(messageEvent); (发广播)    

 

2: 注册事件

EventBus.getDefault().register(this); (注册广播接收器)

 

3:处理消息

@Subscribe(threadMode = ThreadMode.PostThread)

public void XXX(MessageEvent messageEvent) {

...

}

 

对广播了解的话,对比使用很简单

【SCI级别】多策略改进鲸鱼优化算法(HHWOA)和鲸鱼优化算法(WOA)在CEC2017测试集函数F1-F30寻优对比内容概要:本文档主要介绍了一项关于多策略改进鲸鱼优化算法(HHWOA)与标准鲸鱼优化算法(WOA)在CEC2017测试集函数F1-F30上进行寻优性能对比的研究,属于智能优化算法领域的高水平科研工作。文中通过Matlab代码实现算法仿真,重点展示了HHWOA在收敛速度、寻优精度和稳定性方面的优势,体现了多策略改进的有效性。该研究适用于复杂优化问题求解,尤其在工程优化、参数辨识、机器学习超参数调优等领域具有应用潜力。; 适合人群:具备一定算法基础和Matlab编程能力的研究生、科研人员及从事智能优化算法开发与应用的工程技术人员,尤其适合致力于SCI论文写作与算法创新的研究者。; 使用场景及目标:①用于理解鲸鱼优化算法的基本原理及多策略改进思路(如种群初始化、非线性收敛因子、精英反向学习等);②为智能优化算法的性能测试与对比实验提供CEC2017标准测试平台的实现参考;③支撑学术研究中的算法创新与论文复现工作。; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点关注HHWOA的改进策略模块与WOA的差异,通过重复实验验证算法性能,并可将其思想迁移至其他优化算法的改进中,提升科研创新能力。
<think> 我们正在讨论Event Bus(事件总线)的概念、使用方法以及应用场景。根据引用内容,Event Bus是一种在组件或模块间进行通信的机制,它在Vue、Akka、Flutter等框架中都有应用。下面我们将从概念、原理、使用方法和应用场景等方面进行介绍。 ### 一、Event Bus 的概念 Event Bus(事件总线)是一种设计模式,它允许不同的组件或对象通过事件进行通信,而不需要直接相互引用。这种模式的核心是**中央事件处理中心**,组件可以订阅(监听)特定的事件,也可以发布(触发)事件,由事件总线负责将事件传递给所有订阅者[^1][^4]。 ### 二、Event Bus 的原理 1. **发布-订阅模式**: - 组件通过`subscribe`(订阅)方法注册事件监听器 - 其他组件通过`publish`(发布)方法触发事件 - 事件总线负责维护事件与监听器的映射关系 2. **解耦机制**: 事件发布者无需知道谁在监听事件,订阅者也无需知道事件来自何处,从而实现组件间的解耦[^2]。 ### 三、在不同框架中的使用方法 #### 1. Vue 中的 Event Bus 在 Vue2 中,我们可以创建一个空的 Vue 实例作为事件总线[^1][^4]: ```javascript // event-bus.js import Vue from 'vue' export const EventBus = new Vue() ``` **使用示例**: ```javascript // 组件A(发布事件) import { EventBus } from './event-bus.js' EventBus.$emit('toggle-sidebar', true) // 组件B(订阅事件) import { EventBus } from './event-bus.js' EventBus.$on('toggle-sidebar', (isOpen) => { console.log('侧边栏状态:', isOpen) }) ``` 在 Vue3 中,由于移除了`$on`等方法,推荐使用第三方库(如`mitt`)[^5]: ```javascript // useEmitter.js import mitt from 'mitt' export default function useEmitter() { return mitt() } // 组件中使用 import useEmitter from '@/hooks/useEmitter' const emitter = useEmitter() emitter.emit('toggle-sidebar', true) // 发布 emitter.on('toggle-sidebar', isOpen => { /*...*/ }) // 订阅 ``` #### 2. Akka 中的 Event Bus 在 Akka 工具包中,Event Bus 用于Actor之间的消息传递[^2]: ```java // 创建事件总线 MyLookupEventBus bus = new MyLookupEventBus(); // 订阅事件 bus.subscribe(actorRef, "add"); // 发布事件 bus.publish(new Event("add", "insert object")); ``` #### 3. Flutter 中的 Event Bus 使用`event_bus`包实现跨组件通信[^3]: ```dart // 创建全局事件总线 EventBus eventBus = EventBus(); // 定义事件类 class UserLoginEvent { final bool isLogin; UserLoginEvent(this.isLogin); } // 发布事件 eventBus.fire(UserLoginEvent(true)); // 订阅事件 eventBus.on<UserLoginEvent>().listen((event) { print('登录状态: ${event.isLogin}'); }); ``` ### 四、应用场景 1. **跨层级组件通信**(如Vue中非父子组件)[^1] 2. **微服务架构中的服务间通信** 3. **状态变更通知**(如用户登录状态全局通知)[^3] 4. **解耦业务逻辑**(如订单创建后触发邮件发送) ### 五、优缺点分析 | 优点 | 缺点 | |------|------| | 实现组件解耦 | 事件过多时难以维护 | | 简化复杂通信 | 调试困难(事件流不直观) | | 跨框架通用性 | 可能引起内存泄漏(未及时取消订阅)| ### 六、最佳实践 1. **事件命名规范**:使用命名空间(如`user:login`) 2. **及时取消订阅**:避免内存泄漏 ```javascript // Vue示例 created() { EventBus.$on('event', this.handler) } beforeUnmount() { EventBus.$off('event', this.handler) } ``` 3. **避免滥用**:简单场景用`props`/`emit`,复杂状态用Vuex/Pinia[^4] 4. **使用TypeScript**:为事件提供类型安全 ```typescript // 类型化事件总线示例 type Events = { 'toggle-sidebar': boolean 'user-login': { id: string } } const emitter = mitt<Events>() ``` > Event Bus 如同现实中的广播系统:发布者不需要知道听众是谁,听众也不需要知道广播员是谁,只需关注广播内容本身[^2]。 --- §§相关问题§§ 1. Event Bus 与全局状态管理(如Vuex)有何本质区别? 2. 如何避免事件总线导致的内存泄漏问题? 3. 在微服务架构中Event Bus是如何工作的? 4. Event Bus 和观察者模式有什么异同? </think> ### Event Bus 介绍及使用指南 #### 一、Event Bus 基本概念 Event Bus(事件总线)是一种**跨组件通信机制**,它创建一个中央事件处理中心,允许不同组件之间进行通信而不需要直接相互引用。其核心原理是**发布-订阅模式**: 1. **发布者**(Publisher):触发事件并传递数据 2. **订阅者**(Subscriber):监听并处理事件 3. **事件中心**(Event Bus):管理事件分发 ```mermaid graph LR A[组件A] -- 发布事件 --> B[Event Bus] B -- 分发事件 --> C[组件B] B -- 分发事件 --> D[组件C] ``` #### 二、核心特性与价值 1. **解耦组件**:组件间无需知道彼此存在[^1][^4] 2. **跨层级通信**:任意组件(父子/兄弟/无关联组件)均可通信 3. **轻量级方案**:相比 Vuex/Pinia 更简单,适合简单场景 4. **通用性**:在 Vue/Akka/Flutter 等框架中均有实现[^2][^3] #### 三、在 Vue 中的实现与使用 ##### 1. 创建 Event Bus ```javascript // event-bus.js import { createApp } from 'vue' export const eventBus = createApp({}) ``` ##### 2. 发布事件(组件A) ```html <template> <button @click="sendData">发送数据</button> </template> <script setup> import { eventBus } from './event-bus.js' const sendData = () => { // 发布事件并携带数据 eventBus.config.globalProperties.$emit('data-event', { id: 123, value: '测试' }) } </script> ``` ##### 3. 订阅事件(组件B) ```html <script setup> import { onMounted, onUnmounted } from 'vue' import { eventBus } from './event-bus.js' // 事件处理函数 const handleData = (payload) => { console.log('收到数据:', payload) } // 生命周期钩子 onMounted(() => { eventBus.config.globalProperties.$on('data-event', handleData) }) onUnmounted(() => { eventBus.config.globalProperties.$off('data-event', handleData) }) </script> ``` #### 四、最佳实践与注意事项 1. **命名规范**:使用命名空间防止冲突(如 `user:login`) ```javascript // 推荐命名方式 eventBus.emit('cart:item-added', item) ``` 2. **内存管理**:必须移除监听器避免内存泄漏 ```javascript // Vue3 Composition API onUnmounted(() => { eventBus.off('event-name', handler) }) ``` 3. **数据类型控制**:建议使用 TypeScript 定义事件结构 ```typescript // 类型声明 declare module 'vue' { interface ComponentCustomProperties { $emit(event: 'toggle-sidebar', isOpen: boolean): void $on(event: 'toggle-sidebar', callback: (isOpen: boolean) => void): void } } ``` 4. **适用场景**: - 简单应用的状态通知 - 跨路由组件通信 - 第三方插件集成 - 不适合复杂状态管理(此时应选 Vuex/Pinia)[^4] #### 五、与其他技术的对比 | 特性 | Event Bus | Vuex/Pinia | Props/Emits | |---------------------|----------------|-----------------|-----------------| | 通信范围 | 全局 | 全局 | 父子组件 | | 复杂度 | 低 | 中高 | 低 | | 状态管理能力 | 无 | 强 | 无 | | 调试难度 | 较高(事件流) | 中等(Devtools)| 低 | > **设计哲学**:Event Bus 如同现实中的广播系统 - 发布者无需知道谁在接收,接收者只需关注自己感兴趣的消息[^2]。 #### 六、扩展应用模式 1. **带响应式的 Event Bus**: ```javascript import { ref, readonly } from 'vue' // 创建响应式总线 const state = ref({}) export const useEventBus = () => ({ state: readonly(state), setState: (newState) => { state.value = newState } }) ``` 2. **多总线隔离**: ```javascript // 创建独立的事件域 export const createScopedEventBus = () => ({ events: new Map(), on(event, handler) { /* ... */ }, emit(event, payload) { /* ... */ } }) ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值