fastevent 1.1.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/devTools.js +2 -2
- package/dist/devTools.js.map +1 -1
- package/dist/devTools.mjs +2 -2
- package/dist/devTools.mjs.map +1 -1
- package/dist/index.d.mts +304 -53
- package/dist/index.d.ts +304 -53
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +64 -50
- package/readme.md +517 -50
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.github/workflows/publish.yaml +0 -50
- package/.prettierrc.js +0 -20
- package/.vscode/launch.json +0 -20
- package/.vscode/settings.json +0 -18
- package/CHANGELOG.md +0 -60
- package/LICENSE +0 -21
- package/bench.png +0 -0
- package/dist/devTools.d.mts +0 -543
- package/dist/devTools.d.ts +0 -543
- package/example/README.md +0 -54
- package/example/eslint.config.js +0 -28
- package/example/index.html +0 -13
- package/example/package.json +0 -29
- package/example/pnpm-lock.yaml +0 -2047
- package/example/public/vite.svg +0 -1
- package/example/src/App.css +0 -42
- package/example/src/App.tsx +0 -60
- package/example/src/assets/react.svg +0 -1
- package/example/src/index.css +0 -68
- package/example/src/main.tsx +0 -10
- package/example/src/myEvent.ts +0 -32
- package/example/src/vite-env.d.ts +0 -1
- package/example/tsconfig.app.json +0 -26
- package/example/tsconfig.json +0 -7
- package/example/tsconfig.node.json +0 -24
- package/example/vite.config.ts +0 -7
- package/packages/native/index.ts +0 -1
- package/packages/turbo/.zig-cache/h/271c82d991949fd7788fd5451f0ca834.txt +0 -0
- package/packages/turbo/.zig-cache/h/timestamp +0 -0
- package/packages/turbo/.zig-cache/o/ebd7ddab8ffe003267120d598aecce68/dependencies.zig +0 -2
- package/packages/turbo/.zig-cache/z/c8114b040daa461a9e2eabd0357554a4 +0 -0
- package/packages/turbo/build.zig +0 -60
- package/packages/turbo/examples/basic.zig +0 -107
- package/packages/turbo/src/event.zig +0 -251
- package/packages/turbo/src/index.zig +0 -70
- package/packages/turbo/src/scope.zig +0 -104
- package/packages/turbo/src/types.zig +0 -88
- package/packages/turbo/src/utils.zig +0 -171
- package/readme_cn.md +0 -491
- package/src/__benchmarks__/index.ts +0 -3
- package/src/__benchmarks__/multi-level.ts +0 -40
- package/src/__benchmarks__/sample.ts +0 -40
- package/src/__benchmarks__/wildcard.ts +0 -41
- package/src/__tests__/emit.test.ts +0 -106
- package/src/__tests__/emitAsync.test.ts +0 -64
- package/src/__tests__/isPathMatched.test.ts +0 -205
- package/src/__tests__/many.test.ts +0 -22
- package/src/__tests__/meta.test.ts +0 -28
- package/src/__tests__/off.test.ts +0 -214
- package/src/__tests__/onany.test.ts +0 -212
- package/src/__tests__/once.test.ts +0 -70
- package/src/__tests__/retain.test.ts +0 -66
- package/src/__tests__/scope.test.ts +0 -110
- package/src/__tests__/types.test.ts +0 -145
- package/src/__tests__/waitFor.test.ts +0 -116
- package/src/__tests__/wildcard.test.ts +0 -185
- package/src/devTools.ts +0 -166
- package/src/event.ts +0 -741
- package/src/index.ts +0 -3
- package/src/scope.ts +0 -130
- package/src/types.ts +0 -66
- package/src/utils/WeakObjectMap.ts +0 -64
- package/src/utils/isPathMatched.ts +0 -40
- package/src/utils/removeItem.ts +0 -16
- package/tsconfig.json +0 -104
- package/tsup.config.ts +0 -30
package/readme_cn.md
DELETED
|
@@ -1,491 +0,0 @@
|
|
|
1
|
-
# FastEvent
|
|
2
|
-
|
|
3
|
-
FastEvent 是一个功能强大的`TypeScript`事件管理库,提供了灵活的事件订阅和发布机制,支持事件通配符、作用域、异步事件等特性。
|
|
4
|
-
|
|
5
|
-
对比`EventEmitter2`,`FastEvent`具有以下优势:
|
|
6
|
-
|
|
7
|
-
- `FastEvent`的性能比`EventEmitter2`高 `1~2`倍左右。
|
|
8
|
-
- `FastEvent`包大小为 `6.xkb`,而`EventEmitter2`为 `43.4kb`。
|
|
9
|
-
- `FastEvent`拥有更丰富的功能。
|
|
10
|
-
|
|
11
|
-
# 安装
|
|
12
|
-
|
|
13
|
-
使用 npm 安装:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install fastevent
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
或使用 yarn:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
yarn add fastevent
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
# 快速入门
|
|
26
|
-
|
|
27
|
-
## 基本使用
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { FastEvent } from 'fastevent';
|
|
31
|
-
|
|
32
|
-
// 创建事件实例
|
|
33
|
-
const events = new FastEvent();
|
|
34
|
-
|
|
35
|
-
// 订阅事件
|
|
36
|
-
events.on('user/login', (message) => {
|
|
37
|
-
console.log('用户登录:', message.payload);
|
|
38
|
-
console.log('事件类型:', message.type);
|
|
39
|
-
console.log('元数据:', message.meta);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// 发布事件 - 方式1:参数形式
|
|
43
|
-
events.emit('user/login', { id: 1, name: 'Alice' });
|
|
44
|
-
|
|
45
|
-
// 发布事件 - 方式2:消息对象形式
|
|
46
|
-
events.emit({
|
|
47
|
-
type: 'user/login',
|
|
48
|
-
payload: { id: 1, name: 'Alice' },
|
|
49
|
-
meta: { timestamp: Date.now() },
|
|
50
|
-
});
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
# 指南
|
|
54
|
-
|
|
55
|
-
## 事件消息格式
|
|
56
|
-
|
|
57
|
-
FastEvent 使用标准化的消息格式处理所有事件:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
type FastEventMessage<T = string, P = any, M = unknown> = {
|
|
61
|
-
type: T; // 事件类型
|
|
62
|
-
payload: P; // 事件数据
|
|
63
|
-
meta: M; // 事件元数据
|
|
64
|
-
};
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
事件监听器始终接收这个消息对象,提供了一致的方式来访问事件数据和元数据。
|
|
68
|
-
|
|
69
|
-
## 事件通配符
|
|
70
|
-
|
|
71
|
-
FastEvent 支持两种通配符:
|
|
72
|
-
|
|
73
|
-
- `*`: 匹配单层路径
|
|
74
|
-
- `**`: 匹配多层路径
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
const events = new FastEvent();
|
|
78
|
-
|
|
79
|
-
// 匹配 user/*/login
|
|
80
|
-
events.on('user/*/login', (message) => {
|
|
81
|
-
console.log('任何用户类型的登录:', message.payload);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// 匹配 user 下的所有事件
|
|
85
|
-
events.on('user/**', (message) => {
|
|
86
|
-
console.log('所有用户相关事件:', message.payload);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// 触发事件
|
|
90
|
-
events.emit('user/admin/login', { id: 1 }); // 两个处理器都会被调用
|
|
91
|
-
events.emit('user/admin/profile/update', { name: 'New' }); // 只有 ** 处理器会被调用
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## 事件作用域
|
|
95
|
-
|
|
96
|
-
作用域允许你在特定的命名空间下处理事件。注意,作用域与父事件发射器共享相同的监听器表:
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
const events = new FastEvent();
|
|
100
|
-
|
|
101
|
-
// 创建用户相关的作用域
|
|
102
|
-
const userScope = events.scope('user');
|
|
103
|
-
|
|
104
|
-
// 以下两种方式等效:
|
|
105
|
-
userScope.on('login', handler);
|
|
106
|
-
events.on('user/login', handler);
|
|
107
|
-
|
|
108
|
-
// 以下两种方式也等效:
|
|
109
|
-
userScope.emit('login', data);
|
|
110
|
-
events.emit('user/login', data);
|
|
111
|
-
|
|
112
|
-
// 清除作用域中的所有监听器
|
|
113
|
-
userScope.offAll(); // 等效于 events.offAll('user')
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## 监听器选项
|
|
117
|
-
|
|
118
|
-
订阅事件时可以指定额外的选项:
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
interface FastEventListenOptions {
|
|
122
|
-
// 监听器被调用的次数(0表示无限次,1表示一次)
|
|
123
|
-
count?: number;
|
|
124
|
-
// 将监听器添加到监听器数组的开头
|
|
125
|
-
prepend?: boolean;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 示例:监听前3次事件
|
|
129
|
-
events.on('data', handler, { count: 3 });
|
|
130
|
-
|
|
131
|
-
// 示例:确保处理器在其他监听器之前被调用
|
|
132
|
-
events.on('important', handler, { prepend: true });
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## 移除监听器
|
|
136
|
-
|
|
137
|
-
FastEvent 提供多种移除监听器的方式:
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
// 移除特定监听器
|
|
141
|
-
events.off(listener);
|
|
142
|
-
|
|
143
|
-
// 移除某个事件的所有监听器
|
|
144
|
-
events.off('user/login');
|
|
145
|
-
|
|
146
|
-
// 移除某个事件的特定监听器
|
|
147
|
-
events.off('user/login', listener);
|
|
148
|
-
|
|
149
|
-
// 使用通配符模式移除监听器
|
|
150
|
-
events.off('user/*');
|
|
151
|
-
|
|
152
|
-
// 移除所有监听器
|
|
153
|
-
events.offAll();
|
|
154
|
-
|
|
155
|
-
// 移除某个前缀下的所有监听器
|
|
156
|
-
events.offAll('user');
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
## 一次性事件
|
|
160
|
-
|
|
161
|
-
使用 `once` 订阅只触发一次的事件:
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
const events = new FastEvent();
|
|
165
|
-
|
|
166
|
-
events.once('startup', () => {
|
|
167
|
-
console.log('应用启动');
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// 等效于:
|
|
171
|
-
events.on('startup', handler, { count: 1 });
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## 异步事件
|
|
175
|
-
|
|
176
|
-
支持异步事件处理:
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
const events = new FastEvent();
|
|
180
|
-
|
|
181
|
-
events.on('data/fetch', async () => {
|
|
182
|
-
const response = await fetch('https://api.example.com/data');
|
|
183
|
-
return await response.json();
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// 异步发布事件返回所有结果/错误的数组
|
|
187
|
-
const results = await events.emitAsync('data/fetch');
|
|
188
|
-
console.log('所有处理器的结果:', results);
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## 监听器返回值
|
|
192
|
-
|
|
193
|
-
`emit` 和 `emitAsync` 方法都会返回所有事件监听器的执行结果:
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
const events = new FastEvent();
|
|
197
|
-
|
|
198
|
-
// 同步监听器的返回值
|
|
199
|
-
events.on('calculate', () => 1);
|
|
200
|
-
events.on('calculate', () => 2);
|
|
201
|
-
events.on('calculate', () => 3);
|
|
202
|
-
|
|
203
|
-
// 获取返回值数组
|
|
204
|
-
const results = events.emit('calculate');
|
|
205
|
-
console.log('结果:', results); // [1, 2, 3]
|
|
206
|
-
|
|
207
|
-
// 异步监听器
|
|
208
|
-
events.on('process', async () => '结果 1');
|
|
209
|
-
events.on('process', async () => '结果 2');
|
|
210
|
-
|
|
211
|
-
// 获取异步结果/错误数组
|
|
212
|
-
const asyncResults = await events.emitAsync('process');
|
|
213
|
-
console.log('异步结果:', asyncResults); // ['结果 1', '结果 2']
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
对于异步事件,`emitAsync` 会等待所有监听器完成执行,并返回一个数组,包含所有监听器的解析值,如果监听器执行失败则包含错误对象。
|
|
217
|
-
|
|
218
|
-
## 事件等待
|
|
219
|
-
|
|
220
|
-
使用 `waitFor` 等待特定事件发生:
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
const events = new FastEvent();
|
|
224
|
-
|
|
225
|
-
async function waitForLogin() {
|
|
226
|
-
try {
|
|
227
|
-
// 等待登录事件,超时时间 5 秒
|
|
228
|
-
const userData = await events.waitFor('user/login', 5000);
|
|
229
|
-
console.log('用户已登录:', userData);
|
|
230
|
-
} catch (error) {
|
|
231
|
-
console.log('登录等待超时');
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
waitForLogin();
|
|
236
|
-
// 稍后触发登录事件
|
|
237
|
-
events.emit('user/login', { id: 1, name: 'Alice' });
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## 保留事件数据
|
|
241
|
-
|
|
242
|
-
保留最后一次事件数据,新的订阅者会立即收到该数据:
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
const events = new FastEvent();
|
|
246
|
-
|
|
247
|
-
// 发布事件并保留
|
|
248
|
-
events.emit('config/update', { theme: 'dark' }, true);
|
|
249
|
-
|
|
250
|
-
// 之后的订阅者会立即收到保留的数据
|
|
251
|
-
events.on('config/update', (message) => {
|
|
252
|
-
console.log('配置:', message.payload); // 立即输出: 配置: { theme: 'dark' }
|
|
253
|
-
});
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
## 多级事件
|
|
257
|
-
|
|
258
|
-
支持发布和订阅多级事件。
|
|
259
|
-
|
|
260
|
-
默认使用 `/` 作为事件路径分隔符,你也可以使用自定义的分隔符:
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
const events = new FastEvent({
|
|
264
|
-
delimiter: '.',
|
|
265
|
-
});
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
## 全局事件监听
|
|
269
|
-
|
|
270
|
-
使用 `onAny` 监听所有事件:
|
|
271
|
-
|
|
272
|
-
```typescript
|
|
273
|
-
const events = new FastEvent();
|
|
274
|
-
|
|
275
|
-
events.onAny((message) => {
|
|
276
|
-
console.log(`事件 ${message.type} 被触发:`, message.payload);
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
// 也可以使用 prepend 选项
|
|
280
|
-
events.onAny(handler, { prepend: true });
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## 元数据(Meta)
|
|
284
|
-
|
|
285
|
-
元数据是一种为事件提供额外上下文信息的机制。你可以在全局范围内设置元数据,也可以为单个事件添加特定的元数据。
|
|
286
|
-
|
|
287
|
-
### 全局元数据
|
|
288
|
-
|
|
289
|
-
在创建 FastEvent 实例时设置全局元数据:
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
const events = new FastEvent({
|
|
293
|
-
meta: {
|
|
294
|
-
version: '1.0',
|
|
295
|
-
environment: 'production',
|
|
296
|
-
},
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
events.on('user/login', (message) => {
|
|
300
|
-
console.log('事件数据:', message.payload);
|
|
301
|
-
console.log('元数据:', message.meta); // 包含 type、version 和 environment
|
|
302
|
-
});
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### 事件特定元数据
|
|
306
|
-
|
|
307
|
-
在发布事件时可以传递额外的元数据,它会与全局元数据合并:
|
|
308
|
-
|
|
309
|
-
```typescript
|
|
310
|
-
const events = new FastEvent({
|
|
311
|
-
meta: { app: 'MyApp' },
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
// 在发布事件时添加特定的元数据
|
|
315
|
-
events.emit(
|
|
316
|
-
'order/create',
|
|
317
|
-
{ orderId: '123' }, // 事件数据
|
|
318
|
-
false, // 不保留
|
|
319
|
-
{ timestamp: Date.now() }, // 事件特定的元数据
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
// 监听器接收合并后的元数据
|
|
323
|
-
events.on('order/create', (message) => {
|
|
324
|
-
console.log('订单:', message.payload); // { orderId: '123' }
|
|
325
|
-
console.log('元数据:', message.meta); // { type: 'order/create', app: 'MyApp', timestamp: ... }
|
|
326
|
-
});
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## 错误处理
|
|
330
|
-
|
|
331
|
-
FastEvent 提供了错误处理机制:
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
const events = new FastEvent({
|
|
335
|
-
ignoreErrors: true, // 默认为 true,不会抛出错误
|
|
336
|
-
onListenerError: (type, error) => {
|
|
337
|
-
console.error(`处理事件 ${type} 时发生错误:`, error);
|
|
338
|
-
},
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
events.on('process', () => {
|
|
342
|
-
throw new Error('处理失败');
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
// 不会抛出错误,而是触发 onListenerError
|
|
346
|
-
events.emit('process');
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## 泛型参数
|
|
350
|
-
|
|
351
|
-
FastEvent 支持三个泛型类型参数来实现精确的类型控制:
|
|
352
|
-
|
|
353
|
-
```typescript
|
|
354
|
-
class FastEvent<
|
|
355
|
-
Events extends Record<string, any> = Record<string, any>,
|
|
356
|
-
Meta extends Record<string, any> = Record<string, any>,
|
|
357
|
-
Types extends keyof Events = keyof Events
|
|
358
|
-
>
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
1. `Events`:定义事件类型和对应的载荷(payload)类型的映射
|
|
362
|
-
2. `Meta`:定义可以附加到事件的元数据类型
|
|
363
|
-
3. `Types`:所有事件类型的联合类型(通常从 Events 中推导)
|
|
364
|
-
|
|
365
|
-
### 基本类型安全
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
// 定义事件类型
|
|
369
|
-
interface MyEvents {
|
|
370
|
-
'user/login': { id: number; name: string };
|
|
371
|
-
'user/logout': { id: number };
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// 创建带类型的事件发射器
|
|
375
|
-
const events = new FastEvent<MyEvents>();
|
|
376
|
-
|
|
377
|
-
// 事件名称和数据类型检查
|
|
378
|
-
events.on('user/login', (message) => {
|
|
379
|
-
// message.payload 的类型为 { id: number; name: string }
|
|
380
|
-
const { id, name } = message.payload;
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
// 错误:错误的事件名称
|
|
384
|
-
events.emit('wrong/event', {});
|
|
385
|
-
|
|
386
|
-
// 错误:错误的数据类型
|
|
387
|
-
events.emit('user/login', { wrong: 'type' });
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### 自定义元数据类型
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
// 定义元数据结构
|
|
394
|
-
interface MyMeta {
|
|
395
|
-
timestamp: number;
|
|
396
|
-
source: string;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// 创建带自定义元数据的事件发射器
|
|
400
|
-
const events = new FastEvent<MyEvents, MyMeta>();
|
|
401
|
-
|
|
402
|
-
events.on('user/login', (message) => {
|
|
403
|
-
// message.meta 的类型为 MyMeta
|
|
404
|
-
const { timestamp, source } = message.meta;
|
|
405
|
-
console.log(`来自 ${source} 的登录,时间:${timestamp}`);
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
// 发送带类型化元数据的事件
|
|
409
|
-
events.emit('user/login', { id: 1, name: 'Alice' }, false, { timestamp: Date.now(), source: 'web' });
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### 高级类型用法
|
|
413
|
-
|
|
414
|
-
```typescript
|
|
415
|
-
// 定义具有不同载荷类型的事件
|
|
416
|
-
interface ComplexEvents {
|
|
417
|
-
'data/number': number;
|
|
418
|
-
'data/string': string;
|
|
419
|
-
'data/object': { value: any };
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const events = new FastEvent<ComplexEvents>();
|
|
423
|
-
|
|
424
|
-
// TypeScript 确保每个事件的类型安全
|
|
425
|
-
events.on('data/number', (message) => {
|
|
426
|
-
const sum = message.payload + 1; // payload 的类型为 number
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
events.on('data/string', (message) => {
|
|
430
|
-
const upper = message.payload.toUpperCase(); // payload 的类型为 string
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
events.on('data/object', (message) => {
|
|
434
|
-
const value = message.payload.value; // payload 的类型为 { value: any }
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
// 所有的事件发送都会进行类型检查
|
|
438
|
-
events.emit('data/number', 42);
|
|
439
|
-
events.emit('data/string', 'hello');
|
|
440
|
-
events.emit('data/object', { value: true });
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
## 自定义选项
|
|
444
|
-
|
|
445
|
-
FastEvent 构造函数支持多个选项:
|
|
446
|
-
|
|
447
|
-
```typescript
|
|
448
|
-
const events = new FastEvent({
|
|
449
|
-
// 事件路径分隔符,默认为 '/'
|
|
450
|
-
delimiter: '.',
|
|
451
|
-
// 事件处理器的上下文
|
|
452
|
-
context: null,
|
|
453
|
-
// 元数据,会传递给所有事件处理器
|
|
454
|
-
meta: { ... },
|
|
455
|
-
|
|
456
|
-
// 错误处理
|
|
457
|
-
ignoreErrors: true,
|
|
458
|
-
onListenerError: (type, error) => {
|
|
459
|
-
console.error(`事件错误:`, type, error);
|
|
460
|
-
},
|
|
461
|
-
|
|
462
|
-
// 监听器添加/移除的回调
|
|
463
|
-
onAddListener: (path, listener) => {
|
|
464
|
-
console.log('添加监听器:', path);
|
|
465
|
-
},
|
|
466
|
-
onRemoveListener: (path, listener) => {
|
|
467
|
-
console.log('移除监听器:', path);
|
|
468
|
-
},
|
|
469
|
-
onClearListeners: () => {
|
|
470
|
-
console.log('清空监听器:', path);
|
|
471
|
-
},
|
|
472
|
-
onExecuteListener: (message: FastEventMessage, returns: any[], listeners: (FastEventListener<any, any, any> | [FastEventListener<any, any>, number])[]) => {
|
|
473
|
-
console.log('监听器执行后的回调:');
|
|
474
|
-
}
|
|
475
|
-
});
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
### 调试
|
|
479
|
-
|
|
480
|
-
启用`debug=true`并导入`fastevent/devtools`,可以在`Redux Dev Tools`中查看事件.
|
|
481
|
-
|
|
482
|
-
```ts
|
|
483
|
-
import 'fastevent/devtools';
|
|
484
|
-
const emitter = new FastEvent<MyEvents>({
|
|
485
|
-
debug: true,
|
|
486
|
-
});
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
# 性能
|
|
490
|
-
|
|
491
|
-

|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Bench } from 'tinybench';
|
|
2
|
-
import { FastEvent } from '../event';
|
|
3
|
-
import { EventEmitter2 } from 'eventemitter2';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const bench = new Bench({
|
|
7
|
-
time: 1000,
|
|
8
|
-
iterations: 100,
|
|
9
|
-
});
|
|
10
|
-
const fastEmitter = new FastEvent()
|
|
11
|
-
const emitter2 = new EventEmitter2({
|
|
12
|
-
wildcard: true,
|
|
13
|
-
delimiter: '.'
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
bench
|
|
17
|
-
.add('[FastEvent] 多级路径事件的发布与订阅', () => {
|
|
18
|
-
return new Promise<void>((resolve) => {
|
|
19
|
-
const subscriber = fastEmitter.on('a/b/c/d/e/f', () => {
|
|
20
|
-
resolve()
|
|
21
|
-
})
|
|
22
|
-
fastEmitter.emit('a/b/c/d/e/f', 1)
|
|
23
|
-
subscriber.off()
|
|
24
|
-
})
|
|
25
|
-
})
|
|
26
|
-
.add('[EventEmitter2] 多级路径事件的发布与订阅', () => {
|
|
27
|
-
return new Promise<void>((resolve) => {
|
|
28
|
-
const subscriber = emitter2.on('a.b.c.d.e.f', () => {
|
|
29
|
-
resolve()
|
|
30
|
-
},{objectify:true})
|
|
31
|
-
emitter2.emit('a.b.c.d.e.f', 1)
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
subscriber.off()
|
|
34
|
-
})
|
|
35
|
-
}) ;
|
|
36
|
-
//
|
|
37
|
-
(async () => {
|
|
38
|
-
await bench.run();
|
|
39
|
-
console.table(bench.table());
|
|
40
|
-
})();
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Bench } from 'tinybench';
|
|
2
|
-
import { FastEvent } from '../event';
|
|
3
|
-
import { EventEmitter2 } from 'eventemitter2';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const bench = new Bench({
|
|
7
|
-
time: 1000,
|
|
8
|
-
iterations: 100,
|
|
9
|
-
});
|
|
10
|
-
const fastEmitter = new FastEvent()
|
|
11
|
-
const emitter2 = new EventEmitter2({
|
|
12
|
-
wildcard: true,
|
|
13
|
-
delimiter: '.'
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
bench
|
|
17
|
-
.add('[FastEvent] 发布与订阅', () => {
|
|
18
|
-
return new Promise<void>((resolve) => {
|
|
19
|
-
const subscriber= fastEmitter.on('x', () => {
|
|
20
|
-
resolve()
|
|
21
|
-
})
|
|
22
|
-
fastEmitter.emit('x', 1)
|
|
23
|
-
subscriber.off()
|
|
24
|
-
})
|
|
25
|
-
})
|
|
26
|
-
.add('[EventEmitter2] 发布与订阅', () => {
|
|
27
|
-
return new Promise<void>((resolve) => {
|
|
28
|
-
const subscriber= emitter2.on('x', () => {
|
|
29
|
-
resolve()
|
|
30
|
-
})
|
|
31
|
-
emitter2.emit('x', 1)
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
subscriber.off()
|
|
34
|
-
})
|
|
35
|
-
}) ;
|
|
36
|
-
//
|
|
37
|
-
(async () => {
|
|
38
|
-
await bench.run();
|
|
39
|
-
console.table(bench.table());
|
|
40
|
-
})();
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Bench } from 'tinybench';
|
|
2
|
-
import { FastEvent } from '../event';
|
|
3
|
-
import { EventEmitter2 } from 'eventemitter2';
|
|
4
|
-
|
|
5
|
-
const bench = new Bench({
|
|
6
|
-
time: 2000,
|
|
7
|
-
iterations: 200,
|
|
8
|
-
});
|
|
9
|
-
const fastEmitter = new FastEvent()
|
|
10
|
-
const emitter2 = new EventEmitter2({
|
|
11
|
-
wildcard: true,
|
|
12
|
-
delimiter: '.'
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
bench
|
|
18
|
-
.add('[FastEvent] 通配符发布与订阅', () => {
|
|
19
|
-
return new Promise<void>((resolve) => {
|
|
20
|
-
const subscriber= fastEmitter.on('a/b/c/*', () => {
|
|
21
|
-
resolve()
|
|
22
|
-
})
|
|
23
|
-
fastEmitter.emit('a/b/c/x', 1)
|
|
24
|
-
subscriber.off()
|
|
25
|
-
})
|
|
26
|
-
})
|
|
27
|
-
.add('[EventEmitter2] 通配符发布与订阅', () => {
|
|
28
|
-
return new Promise<void>((resolve) => {
|
|
29
|
-
const subscriber = emitter2.on('a.b.c.*', () => {
|
|
30
|
-
resolve()
|
|
31
|
-
},{objectify:true})
|
|
32
|
-
emitter2.emit('a.b.c.x', 1)
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
subscriber.off()
|
|
35
|
-
})
|
|
36
|
-
});
|
|
37
|
-
//
|
|
38
|
-
(async () => {
|
|
39
|
-
await bench.run();
|
|
40
|
-
console.table(bench.table());
|
|
41
|
-
})();
|