38 lines
912 B
JavaScript
38 lines
912 B
JavaScript
|
|
class MyEvent {
|
||
|
|
constructor() {
|
||
|
|
// 使用 Object 或 Map 存储,实现 O(1) 级别的查找
|
||
|
|
this.events = new Map()
|
||
|
|
}
|
||
|
|
add(name, call) {
|
||
|
|
if (!this.events.has(name)) {
|
||
|
|
this.events.set(name, [])
|
||
|
|
}
|
||
|
|
this.events.get(name).push(call)
|
||
|
|
}
|
||
|
|
remove(name, call) {
|
||
|
|
if (!this.events.has(name)) return
|
||
|
|
|
||
|
|
if (!call) {
|
||
|
|
this.events.delete(name)
|
||
|
|
} else {
|
||
|
|
const callbacks = this.events.get(name)
|
||
|
|
const index = callbacks.indexOf(call)
|
||
|
|
if (index !== -1) {
|
||
|
|
callbacks.splice(index, 1)
|
||
|
|
}
|
||
|
|
// 如果该事件没有监听者了,彻底清理 key
|
||
|
|
if (callbacks.length === 0) {
|
||
|
|
this.events.delete(name)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
emit(name, data) {
|
||
|
|
const callbacks = this.events.get(name)
|
||
|
|
if (callbacks) {
|
||
|
|
// 使用 slice() 镜像一份副本,防止在执行回调过程中有 remove 操作导致索引错乱
|
||
|
|
callbacks.slice().forEach((cb) => cb(data))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
export default new MyEvent()
|