-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEventEmitter.ts
More file actions
104 lines (83 loc) · 3.37 KB
/
EventEmitter.ts
File metadata and controls
104 lines (83 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
export type EventListener = (e:any) => void;
export interface EventHandler {
handleEvent(e: any): void
}
export type EventCallback = EventListener|EventHandler;
function invokeEventCallback(callback: EventCallback, event: any){
if((<EventHandler>callback).handleEvent)
(<EventHandler>callback).handleEvent(event);
else (<EventListener>callback)(event)
}
interface EventCallbackDict {
[key: string]: EventCallback[]
}
function insertHandler(collection: EventCallbackDict, type: string, listener: EventCallback){
if(!collection[type]) collection[type] = [];
const list = collection[type];
if(!list.includes(listener)) list.push(listener);
}
function removeHandler(collection: EventCallbackDict, type: string, listener: EventCallback){
const list = collection[type];
if(list){
const index = list.indexOf(listener);
index!==-1 && list.splice(index, 1);
}
}
function invokeHandler(collection: EventCallbackDict, type: string, event: any){
if(!collection[type]) return;
for(let handler of collection[type]){
invokeEventCallback(handler, event);
}
}
export default class EventEmitter<T extends string = string> {
private handlers: EventCallbackDict = {};
private onceHandlers: EventCallbackDict = {};
/**@description 缓存的最后一次事件,用于后添加侦听器可以接收最后一次事件*/
private cachedValue: {[key:string]: any} = {};
/**@description 冒泡最后一个缓存事件 */
private emitCachedEvent(type: string, handler: EventCallback){
if(this.cachedValue[type]){
invokeEventCallback(handler, this.cachedValue[type]);
}
}
addEventListener(type: T, handler: EventCallback):void
addEventListener(type: string, handler: EventCallback):void
addEventListener(type: string, handler: EventCallback){
this.emitCachedEvent(type.toString(), handler);
insertHandler(this.handlers, type.toString(), handler);
}
removeEventListener(type: T, handler: EventCallback):void
removeEventListener(type: string, handler: EventCallback):void
removeEventListener(type: string, handler: EventCallback){
removeHandler(this.handlers, type, handler);
removeHandler(this.onceHandlers, type, handler);
}
once(type: T, handler: EventCallback):void
once(type: string, handler: EventCallback):void
once(type: string, handler: EventCallback){
this.emitCachedEvent(type, handler);
insertHandler(this.onceHandlers, type, handler);
}
on(type: T, handler: EventCallback):void
on(type: string, handler: EventCallback):void
on(type: string, handler: EventCallback){
this.addEventListener(type, handler);
}
off(type: T, handler: EventCallback):void
off(type: string, handler: EventCallback):void
off(type: string, handler: EventCallback){
this.removeEventListener(type, handler);
}
trigger(type: T, event?: any, cache?: boolean): void
trigger(type: string, event?: any, cache?: boolean): void
trigger(type: string, event: any = { type }, cache: boolean = false){
if(cache){
this.cachedValue[type] = event;
}
invokeHandler(this.handlers, type, event);
invokeHandler(this.onceHandlers, type, event);
}
destory(){
this.handlers = this.onceHandlers = this.cachedValue = null;
}
}