-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathEventEmitter.ts
137 lines (114 loc) · 3.75 KB
/
EventEmitter.ts
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* @see {@link https://nodejs.org/api/events.html|node EventEmitter}
*/
type listener = {
listener?: Function
} & Function
class EventEmitter {
// 默认最大订阅数10
static defaultMaxListeners = 10
listenerStore: Record<string, listener[] | undefined>
maxListenerCount: number
constructor({ maxListenerCount }: { maxListenerCount?: number }) {
// 使用对象而不是数组是因为一个 emitter 可以订阅不同的事件
this.listenerStore = {}
this.maxListenerCount = maxListenerCount || EventEmitter.defaultMaxListeners
}
// 添加订阅
on(eventName: string, listener: Function, prepend: boolean = false) {
if (!this.listenerStore[eventName]) {
this.listenerStore[eventName] = [listener]
} else if (prepend) {
this.listenerStore[eventName]!.unshift(listener)
} else {
this.listenerStore[eventName]!.push(listener)
}
// maxListenersCount 等于 0 时等同于 Infinity
const currentListenersCount = this.listenerStore[eventName]!.length
// 添加的事件超出最大事件数会报警告
if (currentListenersCount > (this.maxListenerCount || Infinity)) {
console.warn(
`You had add ${currentListenersCount}listeners, more than the max listeners count: ${this.maxListenerCount}`
)
}
return this
}
// 删除订阅 如果同一个函数被多次添加为 listener,需要多次调用 off
off(eventName: string, listener: Function) {
if (!this.listenerStore[eventName]) {
return
}
const index = this.listenerStore[eventName]!.findIndex(
(existListener) => existListener === listener || existListener.listener === listener
)
if (index !== -1) {
this.listenerStore[eventName]!.splice(index, 1)
}
return this
}
// 只订阅一次 使用闭包在执行后 off 掉自身即可
once(eventName, listener, prepend = false) {
const onceListener = (...args) => {
listener(...args)
this.off(eventName, onceListener)
}
onceListener.listener = listener
this.on(eventName, onceListener, prepend)
return this
}
// 按照注册的顺序同步执行所有事件名为 event 的 listener
// 如果还有事件名为 event 的 listener 返回 true,否则返回 false
emit(eventName, ...args) {
if (this.listenerStore[eventName] && this.listenerStore[eventName]!.length > 0) {
const listenersCopy = [...this.listenerStore[eventName]!]
listenersCopy.forEach((listener) => listener(...args))
return true
}
return false
}
listeners(eventName) {
return this.listenerStore[eventName]
? this.listenerStore[eventName]!.map((listener) =>
listener.listener ? listener.listener : listener,
)
: []
}
rawListeners(eventName) {
return this.listenerStore[eventName] ? this.listenerStore[eventName] : []
}
prependListener(eventName, listener) {
return this.on(eventName, listener, true)
}
prependOnceListener(eventName, listener) {
return this.once(eventName, listener, true)
}
addListener(eventName, listener) {
return this.on(eventName, listener)
}
removeListener(eventName, listener) {
return this.off(eventName, listener)
}
getMaxListeners() {
return this.maxListenerCount
}
setMaxListeners(n) {
// 必须为非负数
if (typeof n !== 'number' || n < 0) {
throw new Error(
`The value of "n" is out of range. It must be a non-negative number. Received '${n}'`,
)
}
this.maxListenerCount = n
return this
}
removeAllListeners(eventName) {
if (!eventName) {
Object.keys(this.listenerStore).forEach((_eventName) => {
this.listenerStore[_eventName] = undefined
})
} else {
this.listenerStore[eventName] = undefined
}
return this
}
}