Skip to content

Commit 77f4d3f

Browse files
authored
Emitter: use Set for "once"
Refs: #267 Refs: #293 Refs: #291
1 parent e180d96 commit 77f4d3f

File tree

2 files changed

+24
-36
lines changed

2 files changed

+24
-36
lines changed

lib/events.js

+22-34
Original file line numberDiff line numberDiff line change
@@ -89,31 +89,36 @@ class Emitter {
8989
}
9090
const on = event.on.slice();
9191
const promises = on.map(async (fn) => fn(value));
92-
if (event.once.length > 0) {
93-
const on = new Array(event.on.length);
92+
if (event.once.size > 0) {
93+
const len = event.on.length;
94+
const on = new Array(len);
9495
let index = 0;
95-
for (let i = 0, len = event.on.length; i < len; i++) {
96+
for (let i = 0; i < len; i++) {
9697
const listener = event.on[i];
97-
if (!event.once.includes(listener)) on[index++] = listener;
98+
if (!event.once.has(listener)) on[index++] = listener;
99+
}
100+
if (index === 0) {
101+
this.#events.delete(eventName);
102+
return Promise.resolve();
98103
}
99104
on.length = index;
100-
if (index > 0) this.#events.set(eventName, { on, once: [] });
101-
else this.#events.delete(eventName);
105+
this.#events.set(eventName, { on, once: new Set() });
102106
}
103107
return Promise.all(promises).then(() => undefined);
104108
}
105109

106110
#addListener(eventName, listener, once) {
107111
let event = this.#events.get(eventName);
108112
if (!event) {
109-
event = { on: [listener], once: once ? [listener] : [] };
113+
const on = [listener];
114+
event = { on, once: once ? new Set(on) : new Set() };
110115
this.#events.set(eventName, event);
111116
} else {
112117
if (event.on.includes(listener)) {
113118
throw new Error('Duplicate listeners detected');
114119
}
115120
event.on.push(listener);
116-
if (once) event.once.push(listener);
121+
if (once) event.once.add(listener);
117122
}
118123
if (event.on.length > this.#maxListeners) {
119124
throw new Error(
@@ -135,10 +140,9 @@ class Emitter {
135140
if (!listener) return void this.#events.delete(eventName);
136141
const event = this.#events.get(eventName);
137142
if (!event) return;
138-
const onIndex = event.on.indexOf(listener);
139-
if (onIndex > -1) event.on.splice(onIndex, 1);
140-
const onceIndex = event.once.indexOf(listener);
141-
if (onceIndex > -1) event.once.splice(onceIndex, 1);
143+
const index = event.on.indexOf(listener);
144+
if (index > -1) event.on.splice(index, 1);
145+
event.once.delete(listener);
142146
}
143147

144148
toPromise(eventName) {
@@ -157,31 +161,15 @@ class Emitter {
157161
}
158162

159163
listeners(eventName) {
160-
if (eventName) {
161-
const event = this.#events.get(eventName);
162-
return event ? event.on : [];
163-
}
164-
const listeners = new Set();
165-
for (const event of this.#events.values()) {
166-
for (let i = 0, len = event.on.length; i < len; i++) {
167-
listeners.add(event.on[i]);
168-
}
169-
}
170-
return Array.from(listeners);
164+
if (!eventName) throw new Error('Expected eventName');
165+
const event = this.#events.get(eventName);
166+
return event ? event.on : [];
171167
}
172168

173169
listenerCount(eventName) {
174-
if (eventName) {
175-
const event = this.#events.get(eventName);
176-
return event ? event.on.length : 0;
177-
}
178-
const listeners = new Set();
179-
for (const event of this.#events.values()) {
180-
for (let i = 0, len = event.on.length; i < len; i++) {
181-
listeners.add(event.on[i]);
182-
}
183-
}
184-
return listeners.size;
170+
if (!eventName) throw new Error('Expected eventName');
171+
const event = this.#events.get(eventName);
172+
return event ? event.on.length : 0;
185173
}
186174

187175
eventNames() {

metautil.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ export class Emitter {
307307
toAsyncIterable(eventName: EventName): AsyncIterable<unknown>;
308308

309309
clear(eventName?: EventName): void;
310-
listeners(eventName?: EventName): Listener[];
311-
listenerCount(eventName?: EventName): number;
310+
listeners(eventName: EventName): Listener[];
311+
listenerCount(eventName: EventName): number;
312312
eventNames(): EventName[];
313313
}

0 commit comments

Comments
 (0)