Skip to content

Commit 42af68e

Browse files
committed
feat!: remove errorHandler
1 parent 1839409 commit 42af68e

File tree

5 files changed

+77
-178
lines changed

5 files changed

+77
-178
lines changed

src/chain.ts

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/emitter.ts

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
import type {
2-
ErrorHandler,
32
EventMap,
43
Listener,
54
OffFunction,
6-
Options,
75
WildcardListener,
86
} from "./types";
97

108
export class LiteEmit<EM extends EventMap = EventMap> {
119
#listenerMap = new Map<keyof EM, Listener<EM[keyof EM]>[]>();
1210
#wildcardListeners: WildcardListener[] = [];
13-
#errorHandler: ErrorHandler | undefined;
14-
15-
constructor(options?: Options) {
16-
this.#errorHandler = options?.errorHandler;
17-
}
18-
1911
public on(event: "*", listener: WildcardListener): OffFunction;
2012
public on<K extends keyof EM>(
2113
event: K,
@@ -61,31 +53,25 @@ export class LiteEmit<EM extends EventMap = EventMap> {
6153
return this.on(event, onceListener);
6254
}
6355

64-
#callListenerWithErrorHandler(listener: Listener<any>, args: any[]): void {
65-
try {
66-
const result = listener(...args);
67-
if (result instanceof Promise) {
68-
result.catch((e) => {
69-
this.#errorHandler?.(e);
70-
});
71-
}
72-
} catch (e: unknown) {
73-
this.#errorHandler?.(e);
74-
}
75-
}
56+
public async emit<K extends keyof EM>(
57+
event: K,
58+
...args: EM[K]
59+
): Promise<void> {
60+
const results: any[] = [];
7661

77-
public emit<K extends keyof EM>(event: K, ...args: EM[K]): void {
7862
if (this.#wildcardListeners.length > 0) {
7963
for (const listener of this.#wildcardListeners) {
80-
this.#callListenerWithErrorHandler(listener, [event, ...args]);
64+
results.push(listener(event as any, ...args));
8165
}
8266
}
8367
const listeners = this.#listenerMap.get(event);
8468
if (listeners) {
8569
for (const listener of listeners) {
86-
this.#callListenerWithErrorHandler(listener, args);
70+
results.push(listener(...args));
8771
}
8872
}
73+
74+
return Promise.all(results).then(() => {});
8975
}
9076

9177
public off(): void;

src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
1-
export type { ChainedLiteEmit } from "./chain";
2-
export { chain } from "./chain";
31
export { LiteEmit } from "./emitter";
42
export type * from "./types";

src/types.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
export type EventMap = Record<PropertyKey, any[]>;
22
export type Listener<A extends any[]> = (...args: A) => void | Promise<void>;
33
export type WildcardListener = Listener<[event: string, ...args: string[]]>;
4-
export type ErrorHandler = (e: unknown) => void;
5-
export interface Options {
6-
errorHandler?: ErrorHandler;
7-
}
84
export type OffFunction = () => void;

test/index.test.ts

Lines changed: 68 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, expect, it } from "vitest";
22

3-
import { LiteEmit, chain } from "../src";
3+
import { LiteEmit } from "../src";
44

55
// eslint-disable-next-line ts/consistent-type-definitions
66
type EventMap = {
@@ -10,13 +10,13 @@ type EventMap = {
1010
faq: [];
1111
error: [];
1212
error2: [];
13+
asyncEvent: [string];
14+
asyncEvent2: [number];
15+
concurrentEvent: [string];
16+
promiseErrorEvent: [];
1317
};
1418

15-
const errorMsgs: string[] = [];
16-
17-
const emitter = new LiteEmit<EventMap>({
18-
errorHandler: (s: any) => errorMsgs.push(s.message),
19-
});
19+
const emitter = new LiteEmit<EventMap>();
2020

2121
const Sym = Symbol("d");
2222

@@ -136,120 +136,89 @@ describe("should", () => {
136136
expect(count2).toBe(3);
137137
});
138138

139-
it("errorHandler", () => {
140-
emitter.on("error", () => {
141-
throw new Error("Foo");
142-
});
143-
emitter.emit("error");
144-
145-
expect(errorMsgs[0]).toBe("Foo");
146-
});
147-
148-
it("errorHandler async", () => {
149-
emitter.on("error2", async () => {
150-
throw new Error("Bar");
151-
});
152-
emitter.emit("error2");
139+
describe("await functionality", () => {
140+
it("should handle async listeners", async () => {
141+
let asyncResult = "";
153142

154-
// Wait for async action
155-
setTimeout(() => {
156-
expect(errorMsgs[1]).toBe("Bar");
157-
}, 500);
158-
});
159-
});
160-
161-
describe("chain", () => {
162-
const Sym = Symbol("d");
163-
164-
it("should be chainable and work correctly", () => {
165-
const emitter = new LiteEmit<EventMap>();
166-
const chained = chain(emitter);
167-
let onCount = 0;
168-
let onceCount = 0;
169-
170-
chained
171-
.on("foo", (str) => {
172-
onCount++;
173-
174-
expect(str).toBe("foo");
175-
})
176-
.once("bar", (str, num, symbol) => {
177-
onceCount++;
178-
179-
expect(str).toBe("bar");
180-
expect(num).toBe(42);
181-
expect(symbol).toBe(Sym);
143+
emitter.on("asyncEvent", async (str: string) => {
144+
await new Promise((resolve) => setTimeout(resolve, 10));
145+
asyncResult = `${str}-processed`;
182146
});
183147

184-
chained.emit("foo", "foo");
185-
186-
expect(onCount).toBe(1);
148+
await emitter.emit("asyncEvent", "test");
187149

188-
chained.emit("bar", "bar", 42, Sym);
150+
expect(asyncResult).toBe("test-processed");
151+
});
189152

190-
expect(onceCount).toBe(1);
153+
it("should return a Promise that can be awaited", async () => {
154+
const executionOrder: number[] = [];
191155

192-
// once should not trigger again
193-
chained.emit("bar", "bar", 42, Sym);
156+
emitter.on("asyncEvent2", async (_num: number) => {
157+
executionOrder.push(1);
158+
await new Promise((resolve) => setTimeout(resolve, 10));
159+
executionOrder.push(2);
160+
});
194161

195-
expect(onceCount).toBe(1);
162+
const promise = emitter.emit("asyncEvent2", 42);
196163

197-
// off should work
198-
chained.off("foo").emit("foo", "foo");
164+
expect(promise).toBeInstanceOf(Promise);
199165

200-
expect(onCount).toBe(1);
201-
});
166+
await promise;
202167

203-
it("should handle wildcard listeners", () => {
204-
const emitter = new LiteEmit<EventMap>();
205-
const chained = chain(emitter);
206-
let wildcardCount = 0;
168+
expect(executionOrder).toEqual([1, 2]);
169+
});
207170

208-
chained
209-
.on("*", () => {
210-
wildcardCount++;
211-
})
212-
.emit("foo", "foo")
213-
.emit("bar", "bar", 42, Sym);
171+
it("should execute multiple async listeners concurrently", async () => {
172+
const startTime = Date.now();
173+
const delays: number[] = [];
214174

215-
expect(wildcardCount).toBe(2);
175+
emitter.on("concurrentEvent", async (_str: string) => {
176+
const start = Date.now();
177+
await new Promise((resolve) => setTimeout(resolve, 50));
178+
delays.push(Date.now() - start);
179+
});
216180

217-
chained.off("*").emit("foo", "foo");
181+
emitter.on("concurrentEvent", async (_str: string) => {
182+
const start = Date.now();
183+
await new Promise((resolve) => setTimeout(resolve, 30));
184+
delays.push(Date.now() - start);
185+
});
218186

219-
expect(wildcardCount).toBe(2);
220-
});
187+
await emitter.emit("concurrentEvent", "test");
188+
const totalTime = Date.now() - startTime;
221189

222-
it("should handle off() to clear all listeners", () => {
223-
const emitter = new LiteEmit<EventMap>();
224-
const chained = chain(emitter);
225-
let count = 0;
226-
chained
227-
.on("foo", () => {
228-
count++;
229-
})
230-
.emit("foo", "foo");
190+
// 并发执行,总时间应该接近最长的单个监听器时间,而不是所有时间的总和
191+
expect(totalTime).toBeLessThan(80); // 50ms + 30ms = 80ms,但并发执行应该更少
192+
expect(delays).toHaveLength(2);
193+
});
231194

232-
expect(count).toBe(1);
195+
it("should handle errors in async listeners", async () => {
196+
emitter.on("promiseErrorEvent", async () => {
197+
throw new Error("Async error");
198+
});
233199

234-
chained.off().emit("foo", "foo");
200+
await expect(async () => {
201+
await emitter.emit("promiseErrorEvent");
202+
}).rejects.toThrowError("Async error");
203+
});
235204

236-
expect(count).toBe(1);
237-
});
205+
it("should work with mixed sync and async listeners", async () => {
206+
let syncResult = "";
207+
let asyncResult = "";
238208

239-
it("should unwrap to the original emitter", () => {
240-
const emitter = new LiteEmit<EventMap>();
241-
const chained = chain(emitter);
209+
emitter.on("asyncEvent", (str: string) => {
210+
syncResult = `${str}-sync`;
211+
});
242212

243-
expect(chained.unwrap()).toBe(emitter);
213+
emitter.on("asyncEvent", async (str: string) => {
214+
await new Promise((resolve) => setTimeout(resolve, 10));
215+
asyncResult = `${str}-async`;
216+
});
244217

245-
// Verify that operations on the unwrapped emitter are reflected
246-
let count = 0;
247-
chained
248-
.on("foo", () => {
249-
count++;
250-
})
251-
.emit("foo", "foo");
218+
await emitter.emit("asyncEvent", "mixed");
252219

253-
expect(count).toBe(1);
220+
expect(syncResult).toBe("mixed-sync");
221+
expect(asyncResult).toBe("mixed-async");
222+
});
254223
});
255224
});

0 commit comments

Comments
 (0)