-
Notifications
You must be signed in to change notification settings - Fork 0
/
EventEmitter.mjs
87 lines (70 loc) · 2.09 KB
/
EventEmitter.mjs
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
function isListener(listener) {
if (typeof listener === 'function') {
return true
}
return false;
}
const pureObject = Object.create(null);
export default class EventEmitter {
#events = pureObject;
#addListener(event, listener, once) {
if (!event || !listener) return false;
if (!isListener(listener)) {
throw new TypeError('listener must be a function');
}
const listeners = (this.#events[event] = this.#events[event] || []);
listeners.push({
listener,
once
});
return true;
}
#removeListener(event, listener) {
const listeners = this.#events[event];
if (!listeners) return false;
const index = listeners.findIndex(l => l.listener === listener);
// 如果不是 -1, ~-1 = -(-1 + 1) = 0
if (~index) {
listeners.splice(index, 1);
return true;
}
return false;
}
on(event, listener) {
this.#addListener(event, listener, false);
return this;
};
once(event, listener) {
this.#addListener(event, listener, true);
return this;
};
off(event, listener) {
this.#removeListener(event, listener);
return this;
};
offAll(eventName) {
if (eventName && this.#events[eventName]) {
this.#events[eventName] = []
} else {
this.#events = pureObject
}
return this;
};
emit(event, ...args) {
const listeners = this.#events[event];
if (!listeners) return;
// 倒叙遍历,不,我就不
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
if (!listener) {
continue;
}
listener.listener.apply(this, args);
// TODO??
if (listener.once && this.#removeListener(event, listener.listener)) {
i--;
}
}
return this;
};
}