保存
This commit is contained in:
262
.qoder/repowiki/zh/content/事件系统/事件系统.md
Normal file
262
.qoder/repowiki/zh/content/事件系统/事件系统.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# 事件系统
|
||||
|
||||
<cite>
|
||||
**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)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [核心组件分析](#核心组件分析)
|
||||
3. [接口契约规范](#接口契约规范)
|
||||
4. [事件管理器扩展实现](#事件管理器扩展实现)
|
||||
5. [跨组件通信实例](#跨组件通信实例)
|
||||
6. [错误处理与内存泄漏防范](#错误处理与内存泄漏防范)
|
||||
|
||||
## 简介
|
||||
本文档全面记录了自定义事件总线系统的实现原理与使用方法。基于 `EventBuilderImpl` 类,详细解释 `addEventListener`、`removeEventListener` 和 `notifyEvent` 三个核心方法的工作机制,包括 `once`、`immediate` 等选项的行为特征。文档描述了 `IEventBuilder` 接口的契约规范,并分析了 `DesktopEventManager` 和 `WindowFormEventManager` 如何继承和扩展基础事件功能。同时提供跨组件通信的实际用例,并说明错误处理和内存泄漏防范措施。
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### EventBuilderImpl 实现机制
|
||||
|
||||
`EventBuilderImpl` 是事件总线系统的核心实现类,采用泛型设计支持类型安全的事件管理。其内部通过 `Map<keyof Events, Set<HandlerWrapper<Events[keyof Events]>>>` 结构存储事件处理器,确保高效的事件查找与去重。
|
||||
|
||||
#### 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 {
|
||||
<<interface>>
|
||||
+addEventListener(eventName, handler, options) : void
|
||||
+removeEventListener(eventName, handler) : void
|
||||
+notifyEvent(eventName, ...args) : void
|
||||
}
|
||||
class IDestroyable {
|
||||
<<interface>>
|
||||
+destroy() : void
|
||||
}
|
||||
IEventBuilder --|> IDestroyable : 继承
|
||||
class EventBuilderImpl {
|
||||
-_eventHandlers : Map<string, Set<HandlerWrapper>>
|
||||
+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<F>, once?: boolean} | 配置选项 |
|
||||
| removeEventListener | eventName | keyof Events | 事件名称 |
|
||||
| | handler | F extends Events[E] | 要移除的处理器函数 |
|
||||
| notifyEvent | eventName | keyof Events | 事件名称 |
|
||||
| | ...args | Parameters<F> | 传递给处理器的参数 |
|
||||
|
||||
**Section sources**
|
||||
- [IEventBuilder.ts](file://src/events/IEventBuilder.ts#L1-L46)
|
||||
|
||||
## 事件管理器扩展实现
|
||||
|
||||
### DesktopEventManager 桌面事件管理
|
||||
`DesktopEventManager` 通过实例化 `EventBuilderImpl<IDesktopEvent>` 创建专用的桌面事件总线,定义了桌面应用相关的特定事件类型。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class IDesktopEvent {
|
||||
<<interface>>
|
||||
+desktopAppPosChange(info : IDesktopAppIcon) : void
|
||||
}
|
||||
class desktopEM {
|
||||
+instance of EventBuilderImpl<IDesktopEvent>
|
||||
}
|
||||
desktopEM ..> IDesktopEvent : 类型约束
|
||||
desktopEM ..> EventBuilderImpl : 实例化
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [DesktopEventManager.ts](file://src/events/DesktopEventManager.ts#L1-L16)
|
||||
|
||||
### WindowFormEventManager 窗口表单事件管理
|
||||
`WindowFormEventManager` 提供了窗口生命周期管理的完整事件体系,涵盖最小化、最大化、关闭、聚焦等状态变化。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class IWindowFormEvent {
|
||||
<<interface>>
|
||||
+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<IWindowFormEvent>
|
||||
}
|
||||
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)
|
||||
Reference in New Issue
Block a user