# 事件系统 **Referenced Files in This Document ** - [EventBuilderImpl.ts](file://src/events/impl/EventBuilderImpl.ts) - [IEventBuilder.ts](file://src/events/IEventBuilder.ts) - [DesktopEventManager.ts](file://src/events/DesktopEventManager.ts) - [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts) ## 目录 1. [简介](#简介) 2. [核心组件分析](#核心组件分析) 3. [接口契约规范](#接口契约规范) 4. [事件管理器扩展实现](#事件管理器扩展实现) 5. [跨组件通信实例](#跨组件通信实例) 6. [错误处理与内存泄漏防范](#错误处理与内存泄漏防范) ## 简介 本文档全面记录了自定义事件总线系统的实现原理与使用方法。基于 `EventBuilderImpl` 类,详细解释 `addEventListener`、`removeEventListener` 和 `notifyEvent` 三个核心方法的工作机制,包括 `once`、`immediate` 等选项的行为特征。文档描述了 `IEventBuilder` 接口的契约规范,并分析了 `DesktopEventManager` 和 `WindowFormEventManager` 如何继承和扩展基础事件功能。同时提供跨组件通信的实际用例,并说明错误处理和内存泄漏防范措施。 ## 核心组件分析 ### EventBuilderImpl 实现机制 `EventBuilderImpl` 是事件总线系统的核心实现类,采用泛型设计支持类型安全的事件管理。其内部通过 `Map>>` 结构存储事件处理器,确保高效的事件查找与去重。 #### addEventListener 方法工作机制 该方法用于注册事件监听器,具有以下特性: - **去重机制**:在添加前检查是否已存在相同处理器函数,避免重复绑定 - **即时执行**:当 `options.immediate` 为 `true` 时,立即同步执行一次处理器 - **单次监听**:通过 `options.once` 标记,使监听器在触发后自动移除 - **类型安全**:利用 TypeScript 泛型约束确保事件名与处理器参数类型匹配 ```mermaid flowchart TD Start([开始]) --> ValidateHandler["验证处理器非空"] ValidateHandler --> HasEvent{"是否存在事件队列?"} HasEvent --> |否| CreateSet["创建新的处理器集合"] CreateSet --> AddToSet HasEvent --> |是| GetSet["获取现有集合"] GetSet --> AddToSet AddToSet --> CheckDuplicate{"是否已存在?"} CheckDuplicate --> |否| AddWrapper["添加包装器(once标记)"] AddWrapper --> CheckImmediate{"是否立即执行?"} CheckImmediate --> |是| ExecuteNow["立即执行处理器"] CheckImmediate --> |否| End([结束]) ExecuteNow --> End ``` **Diagram sources** - [EventBuilderImpl.ts](file://src/events/impl/EventBuilderImpl.ts#L20-L46) #### removeEventListener 方法工作机制 该方法通过遍历对应事件的处理器集合,精确匹配并删除指定的处理器函数引用,实现精准解绑。 #### notifyEvent 方法工作机制 通知方法按顺序调用所有注册的处理器,并处理以下特殊情况: - 自动清理标记为 `once` 的监听器 - 捕获并记录处理器执行中的异常,防止中断其他监听器 - 支持任意数量的参数传递 ```mermaid sequenceDiagram participant Publisher as "发布者" participant EventBus as "EventBus" participant Handler1 as "处理器1" participant Handler2 as "处理器2" Publisher->>EventBus : notifyEvent('event', args) EventBus->>EventBus : 获取处理器集合 loop 每个处理器 EventBus->>Handler1 : 执行处理器 Handler1-->>EventBus : 完成 EventBus->>EventBus : 检查once标记 alt 是单次监听 EventBus->>EventBus : 从集合中移除 end EventBus->>Handler2 : 执行处理器 Handler2-->>EventBus : 完成 end EventBus-->>Publisher : 通知完成 Note over Handler1,Handler2 : 异常被捕获,不影响其他处理器执行 ``` **Diagram sources** - [EventBuilderImpl.ts](file://src/events/impl/EventBuilderImpl.ts#L75-L90) **Section sources** - [EventBuilderImpl.ts](file://src/events/impl/EventBuilderImpl.ts#L7-L95) ## 接口契约规范 ### IEventBuilder 接口定义 `IEventBuilder` 接口定义了事件管理器的标准行为契约,继承自 `IDestroyable` 接口以支持资源清理。 ```mermaid classDiagram class IEventBuilder { <> +addEventListener(eventName, handler, options) : void +removeEventListener(eventName, handler) : void +notifyEvent(eventName, ...args) : void } class IDestroyable { <> +destroy() : void } IEventBuilder --|> IDestroyable : 继承 class EventBuilderImpl { -_eventHandlers : Map> +addEventListener() +removeEventListener() +notifyEvent() +destroy() } EventBuilderImpl ..|> IEventBuilder : 实现 ``` **Diagram sources** - [IEventBuilder.ts](file://src/events/IEventBuilder.ts#L13-L46) 接口方法参数说明: | 方法 | 参数 | 类型 | 描述 | |------|------|------|------| | addEventListener | eventName | keyof Events | 事件名称 | | | handler | F extends Events[E] | 事件处理器函数 | | | options | {immediate?: boolean, immediateArgs?: Parameters, once?: boolean} | 配置选项 | | removeEventListener | eventName | keyof Events | 事件名称 | | | handler | F extends Events[E] | 要移除的处理器函数 | | notifyEvent | eventName | keyof Events | 事件名称 | | | ...args | Parameters | 传递给处理器的参数 | **Section sources** - [IEventBuilder.ts](file://src/events/IEventBuilder.ts#L1-L46) ## 事件管理器扩展实现 ### DesktopEventManager 桌面事件管理 `DesktopEventManager` 通过实例化 `EventBuilderImpl` 创建专用的桌面事件总线,定义了桌面应用相关的特定事件类型。 ```mermaid classDiagram class IDesktopEvent { <> +desktopAppPosChange(info : IDesktopAppIcon) : void } class desktopEM { +instance of EventBuilderImpl } desktopEM ..> IDesktopEvent : 类型约束 desktopEM ..> EventBuilderImpl : 实例化 ``` **Diagram sources** - [DesktopEventManager.ts](file://src/events/DesktopEventManager.ts#L1-L16) ### WindowFormEventManager 窗口表单事件管理 `WindowFormEventManager` 提供了窗口生命周期管理的完整事件体系,涵盖最小化、最大化、关闭、聚焦等状态变化。 ```mermaid classDiagram class IWindowFormEvent { <> +windowFormMinimize(id : string) : void +windowFormMaximize(id : string) : void +windowFormRestore(id : string) : void +windowFormClose(id : string) : void +windowFormFocus(id : string) : void +windowFormDataUpdate(data : IWindowFormDataUpdateParams) : void +windowFormCreated() : void } class wfem { +instance of EventBuilderImpl } class IWindowFormDataUpdateParams { +id : string +state : TWindowFormState +width : number +height : number +x : number +y : number } wfem ..> IWindowFormEvent : 类型约束 IWindowFormEvent ..> IWindowFormDataUpdateParams : 引用 ``` **Diagram sources** - [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L1-L61) **Section sources** - [DesktopEventManager.ts](file://src/events/DesktopEventManager.ts#L1-L16) - [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L1-L61) ## 跨组件通信实例 ### 桌面应用位置更新场景 ```typescript // 发布者组件 const updatePosition = (iconInfo) => { desktopEM.notifyEvent('desktopAppPosChange', iconInfo) } // 订阅者组件 desktopEM.addEventListener('desktopAppPosChange', (info) => { console.log('应用位置更新:', info.name, info.x, info.y) }, { immediate: true, immediateArgs: [currentIconInfo] }) ``` ### 窗口状态变更场景 ```typescript // 窗口最小化 wfem.notifyEvent('windowFormMinimize', 'win123') // 监听窗口最小化(仅一次) wfem.addEventListener('windowFormMinimize', (id) => { addToTaskbar(id) }, { once: true }) // 监听所有窗口数据更新 wfem.addEventListener('windowFormDataUpdate', (data) => { saveWindowState(data) }) ``` **Section sources** - [DesktopEventManager.ts](file://src/events/DesktopEventManager.ts#L1-L16) - [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L1-L61) ## 错误处理与内存泄漏防范 ### 错误处理机制 系统在关键执行路径上均包含异常捕获: - 处理器执行时捕获异常,防止中断其他监听器 - 控制台输出错误信息便于调试 - 不抛出异常保证事件总线稳定性 ### 内存泄漏防范措施 1. **及时解绑**:使用 `removeEventListener` 移除不再需要的监听器 2. **单次监听**:对只需执行一次的逻辑使用 `once: true` 选项 3. **资源清理**:实现 `destroy()` 方法清空所有事件处理器 4. **实例管理**:通过单例模式管理事件总线实例生命周期 ```mermaid flowchart TD A[组件挂载] --> B[添加事件监听] B --> C[设置once或immediate] C --> D[组件运行] D --> E{组件卸载?} E --> |是| F[调用removeEventListener] F --> G[或调用destroy清理所有] G --> H[防止内存泄漏] E --> |否| D ``` **Section sources** - [EventBuilderImpl.ts](file://src/events/impl/EventBuilderImpl.ts#L92-L94)