From 6b0214d9a4d5366e293b3b413f29a17346ab2dfe Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 18:19:49 +0800 Subject: [PATCH 01/13] WIP --- modules/conjoin_emitter.ts | 6 ++---- modules/runners/dual.ts | 6 ++---- modules/runners/relay.ts | 30 ++++++++++++++++++++++++++++++ modules/runners/sequence.ts | 14 ++++++-------- modules/runners/series.ts | 9 +++++---- modules/runners/step.ts | 15 ++++++--------- 6 files changed, 51 insertions(+), 29 deletions(-) create mode 100644 modules/runners/relay.ts diff --git a/modules/conjoin_emitter.ts b/modules/conjoin_emitter.ts index 3fe7ca2..388b08c 100644 --- a/modules/conjoin_emitter.ts +++ b/modules/conjoin_emitter.ts @@ -16,6 +16,7 @@ import { CoreEmitter } from "modules/core_emitter.ts"; import { Emitter } from "modules/emitter.ts"; import { SeriesRunner } from "modules/runners/series.ts"; import { ConjoinQueue } from "modules/conjoin_queue.ts"; +import { RelayRunner } from "modules/runners/relay.ts"; import * as helpers from "modules/helpers.ts"; export class ConjoinEmitter extends CoreEmitter @@ -136,10 +137,7 @@ export class ConjoinEmitter extends CoreEmitter return this.prevEvents; }; - if (this.prevEvents instanceof Promise) { - return Promise.resolve(this.prevEvents).then(next); - } - return next(); + return new RelayRunner().exec(this.prevEvents, next, { async: true }); } off(event: ConjoinEvents, handler?: EventHandler): void { diff --git a/modules/runners/dual.ts b/modules/runners/dual.ts index 10f5592..a8b7226 100644 --- a/modules/runners/dual.ts +++ b/modules/runners/dual.ts @@ -4,6 +4,7 @@ import type { } from "modules/types.ts"; import { SequenceRunner } from "modules/runners/sequence.ts"; +import { RelayRunner } from "modules/runners/relay.ts"; /** * Run a dual event handler. @@ -53,9 +54,6 @@ export class DualRunner { * @param args The arguments to pass to the dual handler. */ exec(result: any) { - if (result instanceof Promise) { - return Promise.resolve(result).then((res) => this.dualExec(res)); - } - return this.dualExec(result); + return new RelayRunner().exec(result, (p) => this.dualExec(p)); } } diff --git a/modules/runners/relay.ts b/modules/runners/relay.ts new file mode 100644 index 0000000..07851b1 --- /dev/null +++ b/modules/runners/relay.ts @@ -0,0 +1,30 @@ +import type { EventHandler } from "modules/types.ts"; + +/** Options to RelayRunner */ +export type RelayRunnerOptions = { + /** + * If the prev handler is a promise, it will await for it before executing the next handler. + * @default false + */ + async: boolean; +}; + +/** Handle how to run before and after handler. */ +export class RelayRunner { + /** + * Execute the handler. + * @param prev The result of the previous handler. + * @param next The next handler. + * @param options The options to run the next handler. + */ + exec( + prev: any, + next: T, + options?: Partial, + ): Promise> | ReturnType { + if (prev instanceof Promise) { + return Promise.resolve(prev).then((res) => next(res)); + } + return next(prev); + } +} diff --git a/modules/runners/sequence.ts b/modules/runners/sequence.ts index f048ade..d16beec 100644 --- a/modules/runners/sequence.ts +++ b/modules/runners/sequence.ts @@ -1,6 +1,7 @@ import type { GeneralEventHandlerSignature } from "modules/types.ts"; import { SingleRunner } from "modules/runners/single.ts"; +import { RelayRunner } from "modules/runners/relay.ts"; /** * Run handlers in sequence. @@ -26,18 +27,15 @@ export class SequenceRunner< exec( args: Parameters, index: number = 0, - ): void | Promise { + ): ReturnType | Promise> | void { const profile = this.handlers[index]; if (!profile) return; const result = new SingleRunner(profile).exec(args) as any; - /** - * Wait for the handler to finish before moving to the next handler. - */ - if (profile.options?.async || result instanceof Promise) { - return Promise.resolve(result).then(() => this.exec(args, index + 1)); - } - return this.exec(args, index + 1); + return new RelayRunner().exec( + result, + () => this.exec(args, index + 1), + ) as any; } } diff --git a/modules/runners/series.ts b/modules/runners/series.ts index 489da3c..79e4174 100644 --- a/modules/runners/series.ts +++ b/modules/runners/series.ts @@ -1,6 +1,7 @@ import type { EventName, RegisteredHandlers } from "modules/types.ts"; import { StepRunner } from "modules/runners/step.ts"; +import { RelayRunner } from "modules/runners/relay.ts"; /** * Run handlers each in series. @@ -24,9 +25,9 @@ export class SeriesRunner { if (!key) return; const step = new StepRunner(this.handlers).exec(key); - if (step instanceof Promise) { - return Promise.resolve(step).then(() => this.exec(series, idx + 1)); - } - return this.exec(series, idx + 1); + return new RelayRunner().exec( + step, + () => this.exec(series, idx + 1), + ) as any; } } diff --git a/modules/runners/step.ts b/modules/runners/step.ts index 574a7dc..c5ad15d 100644 --- a/modules/runners/step.ts +++ b/modules/runners/step.ts @@ -9,6 +9,7 @@ import type { import { DualRunner } from "modules/runners/dual.ts"; import { SingleRunner } from "modules/runners/single.ts"; import { SequenceRunner } from "modules/runners/sequence.ts"; +import { RelayRunner } from "modules/runners/relay.ts"; import * as helpers from "modules/helpers.ts"; /** @@ -51,17 +52,13 @@ export class StepRunner { const next = (result: any) => { const dualResult = new DualRunner(duals).exec(!!result); - if (dualResult instanceof Promise) { - return dualResult.then(() => - this.execByIndex(handlers, duals, args, idx + 1) - ); - } + return new RelayRunner().exec( + dualResult, + () => this.execByIndex(handlers, duals, args, idx + 1), + ); }; - if (handler.options?.async) { - return Promise.resolve(result).then(() => next(result)); - } - return next(result); + return new RelayRunner().exec(result, next) as any; } /** From 4af5739cc752ba7894ffb0eda9049deb20969cbb Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:09:48 +0800 Subject: [PATCH 02/13] WIP --- modules/conjoin_emitter.ts | 1 + modules/core_emitter.ts | 14 +++++++------- modules/emitter.ts | 1 + modules/helpers.ts | 11 +++++++++++ modules/types.ts | 7 ++----- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/modules/conjoin_emitter.ts b/modules/conjoin_emitter.ts index 388b08c..92dc5b4 100644 --- a/modules/conjoin_emitter.ts +++ b/modules/conjoin_emitter.ts @@ -77,6 +77,7 @@ export class ConjoinEmitter extends CoreEmitter handler, options: { once: options?.once, + async: options?.async, dual: helpers.isDualHandler(handler), }, } as DualEventHandlerSignature | GeneralEventHandlerSignature; diff --git a/modules/core_emitter.ts b/modules/core_emitter.ts index 5a236df..f438566 100644 --- a/modules/core_emitter.ts +++ b/modules/core_emitter.ts @@ -10,6 +10,7 @@ import type { } from "modules/types.ts"; import { Logger } from "modules/logger.ts"; +import * as helpers from "modules/helpers.ts"; export abstract class CoreEmitter implements XCoreEmitter { protected handlers: RegisteredHandlers; @@ -35,15 +36,14 @@ export abstract class CoreEmitter implements XCoreEmitter { name: EventName, signature: EventHandlerSignature, ): EventUnscriber { - // @ts-ignore TS7053 - const async = signature.handler[Symbol.toStringTag] === "AsyncFunction" || - ("then" in signature.handler); - - signature.options ??= {}; - signature.options.async = async; - if (this.debug) this.logger.debug("on", name, signature); + if ( + signature.options?.async && !helpers.isAsyncFunction(signature.handler) + ) { + delete signature.options.async; + } + const handlers = this.handlers.get(name); if (handlers) { handlers.push(signature); diff --git a/modules/emitter.ts b/modules/emitter.ts index a765552..f287cc8 100644 --- a/modules/emitter.ts +++ b/modules/emitter.ts @@ -29,6 +29,7 @@ export class Emitter extends CoreEmitter implements XevtEmitter { handler, options: { once: options?.once || event === EmitDone, + async: !!options?.async, dual: helpers.isDualHandler(handler), }, } as DualEventHandlerSignature | GeneralEventHandlerSignature; diff --git a/modules/helpers.ts b/modules/helpers.ts index 7272219..b7b4dc0 100644 --- a/modules/helpers.ts +++ b/modules/helpers.ts @@ -26,3 +26,14 @@ export function isDualHandler( "true" in handler || "false" in handler ); } + +/** + * Check if a handler is an async function. + * @param handler The handler to check. + */ +export function isAsyncFunction(handler: any) { + // @ts-ignore TS7053 + return (typeof handler === "function" && + handler[Symbol.toStringTag] === "AsyncFunction") || + ("then" in handler); +} diff --git a/modules/types.ts b/modules/types.ts index 1f8ee3f..22d220d 100644 --- a/modules/types.ts +++ b/modules/types.ts @@ -8,6 +8,7 @@ export type ErrorHandler = (error: unknown) => void; export type EventOptions = { once: boolean; + async: boolean; }; export type DualEventHandler = @@ -19,11 +20,7 @@ export type DualEventHandlerSignature = { name: T; handler: DualEventHandler; options: - & Partial< - EventOptions & { - async: boolean; - } - > + & Partial & { dual: true }; }; From 97478cd4cdd22f5b162aec5e05bf42e0b309d0ce Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:14:25 +0800 Subject: [PATCH 03/13] WIP --- modules/runners/relay.ts | 2 +- modules/runners/sequence.ts | 2 +- modules/runners/step.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/runners/relay.ts b/modules/runners/relay.ts index 07851b1..fb67e70 100644 --- a/modules/runners/relay.ts +++ b/modules/runners/relay.ts @@ -22,7 +22,7 @@ export class RelayRunner { next: T, options?: Partial, ): Promise> | ReturnType { - if (prev instanceof Promise) { + if (prev instanceof Promise && options?.async) { return Promise.resolve(prev).then((res) => next(res)); } return next(prev); diff --git a/modules/runners/sequence.ts b/modules/runners/sequence.ts index d16beec..c98d9ae 100644 --- a/modules/runners/sequence.ts +++ b/modules/runners/sequence.ts @@ -32,10 +32,10 @@ export class SequenceRunner< if (!profile) return; const result = new SingleRunner(profile).exec(args) as any; - return new RelayRunner().exec( result, () => this.exec(args, index + 1), + profile.options, ) as any; } } diff --git a/modules/runners/step.ts b/modules/runners/step.ts index c5ad15d..f3805ca 100644 --- a/modules/runners/step.ts +++ b/modules/runners/step.ts @@ -58,7 +58,7 @@ export class StepRunner { ); }; - return new RelayRunner().exec(result, next) as any; + return new RelayRunner().exec(result, next, handler.options) as any; } /** From 79ff589edbcfa431bc1c1ec80003fa7d85af99a9 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:18:28 +0800 Subject: [PATCH 04/13] WIP --- tests/deno/single_event_test.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index 83d30a3..a53c6d9 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -125,19 +125,15 @@ describe("Xevt - single event", () => { emitter.on( "event", // deno-lint-ignore require-await - async (data) => - new Promise((res) => { - setTimeout(() => { - result.push(data); - res(true); - }, 10); - }), + async (data) => { + result.push(data); + }, ); for (let i = 0; i < 5; i++) { emitter.emit("event", i); } - await delay(100); + await delay(1); assertEquals(result, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); }); }); From 6f06a2702598576d80db0124c53031d7dceae6d5 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:19:14 +0800 Subject: [PATCH 05/13] WIP --- tests/deno/single_event_test.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index a53c6d9..3dc71fb 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -125,9 +125,13 @@ describe("Xevt - single event", () => { emitter.on( "event", // deno-lint-ignore require-await - async (data) => { - result.push(data); - }, + async (data) => + new Promise((res) => { + setTimeout(() => { + result.push(data); + res(true); + }, 10); + }), ); for (let i = 0; i < 5; i++) { From bfc53dd9fe0b0bdecc5d7d8241fb7bcaab1fea7a Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:20:06 +0800 Subject: [PATCH 06/13] WIP --- tests/deno/single_event_test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index 3dc71fb..0f175d0 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -116,7 +116,7 @@ describe("Xevt - single event", () => { assertEquals(result, [1, 2, 3, 4, 5, 6, 7, 8]); }); - it("mix handlers", async () => { + it("mix handlers - blocking", async () => { const emitter = new Xevt(); const result: number[] = []; emitter.on("event", (data) => { @@ -130,14 +130,15 @@ describe("Xevt - single event", () => { setTimeout(() => { result.push(data); res(true); - }, 10); + }, 1); }), + { async: true }, ); for (let i = 0; i < 5; i++) { emitter.emit("event", i); } - await delay(1); + await delay(10); assertEquals(result, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); }); }); From 825096d7dea9a0b32c15770b896e95685c572ad5 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:20:24 +0800 Subject: [PATCH 07/13] WIP --- tests/deno/single_event_test.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index 0f175d0..2930e19 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -141,6 +141,32 @@ describe("Xevt - single event", () => { await delay(10); assertEquals(result, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); }); + + it("mix handlers - non-blocking", async () => { + const emitter = new Xevt(); + const result: number[] = []; + emitter.on("event", (data) => { + result.push(data); + }); + emitter.on( + "event", + // deno-lint-ignore require-await + async (data) => + new Promise((res) => { + setTimeout(() => { + result.push(data); + res(true); + }, 1); + }), + { async: false }, + ); + + for (let i = 0; i < 5; i++) { + emitter.emit("event", i); + } + await delay(10); + assertEquals(result, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); + }); }); describe("Xevt - unscriber", () => { From fbceae74e8b5313f65a1596886476e8c91e4b8c0 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:23:00 +0800 Subject: [PATCH 08/13] WIP --- tests/deno/single_event_test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index 2930e19..85d0845 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -138,7 +138,7 @@ describe("Xevt - single event", () => { for (let i = 0; i < 5; i++) { emitter.emit("event", i); } - await delay(10); + await delay(15); assertEquals(result, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); }); @@ -164,8 +164,8 @@ describe("Xevt - single event", () => { for (let i = 0; i < 5; i++) { emitter.emit("event", i); } - await delay(10); - assertEquals(result, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]); + await delay(15); + assertEquals(result, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); }); }); From 97eede64f5487b254c880aad3e3846750f7f7720 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:24:08 +0800 Subject: [PATCH 09/13] WIP --- tests/deno/multiple_events_test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/deno/multiple_events_test.ts b/tests/deno/multiple_events_test.ts index 36bea20..3951f32 100644 --- a/tests/deno/multiple_events_test.ts +++ b/tests/deno/multiple_events_test.ts @@ -139,7 +139,7 @@ describe("Xevt - multiple events", () => { setTimeout(() => { result++; resolve(true); - }, 10) + }, 1) ); }); emitter.emit("event1"); @@ -150,7 +150,7 @@ describe("Xevt - multiple events", () => { emitter.emit("event2"); emitter.emit("event1"); emitter.emit("event2"); - await delay(100); + await delay(15); assertEquals(result, 4); }); @@ -169,7 +169,7 @@ describe("Xevt - multiple events", () => { emitter.emit("event1"); emitter.emit("event2"); } - await delay(100); + await delay(10); assertEquals(result, [1, 2, 1, 2, 1, 2, 1, 2, 1, 2]); }); }); From 9b2ef0fc52c382580dcbe4cb6c490ea6e9f93e45 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:26:37 +0800 Subject: [PATCH 10/13] wip --- README.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 52d090f..c5cc29a 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,8 @@ console.log(count); // 1 ### Mixed async/sync handlers +Non-blocking in default. + ```typescript const emitter = new Xevt(); const result: number[] = []; @@ -128,27 +130,39 @@ for (let i = 0; i < 5; i++) { emitter.emit("event", i); } -// [0, 0, 1, 1, 2, 2, 3, 3, 4, 4] +// [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] ``` +Blocking mode. + ```typescript const emitter = new Xevt(); const result: number[] = []; -emitter.conjoin(["event1", "event2"], async () => { - result.push(1); -}); -emitter.conjoin(["event1", "event2"], async () => { - result.push(2); +emitter.on("event", (data) => { + result.push(data); }); +emitter.on( + "event", + // deno-lint-ignore require-await + async (data) => + new Promise((res) => { + setTimeout(() => { + result.push(data); + res(true); + }, 1); + }), + { async: true }, +); for (let i = 0; i < 5; i++) { - emitter.emit("event1"); - emitter.emit("event2"); + emitter.emit("event", i); } +await delay(15); -// [1, 2, 1, 2, 1, 2, 1, 2, 1, 2] +// [0, 0, 1, 1, 2, 2, 3, 3, 4, 4] ``` + ## Return unscriber after registered an event ```typescript From a52971e3ec163d34285f47d28f060e8dd0d920d8 Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:37:13 +0800 Subject: [PATCH 11/13] WIP --- README.md | 9 ++++++--- tests/deno/single_event_test.ts | 22 +++++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c5cc29a..b39c311 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,16 @@ await emitter.emit("event"); ### Conditional event handlers. -IMPORTANT: conditional handlers not supported to conjoined event. +IMPORTANT: + +- NOT supported in conjoined events. +- NOT supported any arguments in handlers. +- It will be executed after the triggered event finished. (Blocking mode.) ```typescript const emitter = new Xevt(); const result: any[] = []; -emitter.on("event", (arg: number) => { +emitter.on("event", async (arg: number) => { result.push(arg); return arg % 2 === 0; }); @@ -162,7 +166,6 @@ await delay(15); // [0, 0, 1, 1, 2, 2, 3, 3, 4, 4] ``` - ## Return unscriber after registered an event ```typescript diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index 85d0845..e11ed7b 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -183,11 +183,11 @@ describe("Xevt - unscriber", () => { }); }); -describe("Xevt - on", () => { +describe("Xevt - conditional event handlers", () => { it('should listen event with "on"', () => { const emitter = new Xevt(); const result: number[] = []; - emitter.on("event", (arg: number) => { + emitter.on("event", async (arg: number) => { result.push(arg); return arg % 2 === 0; }); @@ -260,14 +260,18 @@ describe("Xevt - on", () => { }, }); - emitter.on("event", { - true: () => { - result.push(100); - }, - false: () => { - result.push(99); + emitter.on( + "event", + { + true: () => { + result.push(100); + }, + false: () => { + result.push(99); + }, }, - }, { once: true }); + { once: true }, + ); emitter.emit("event", 1); emitter.emit("event", 2); From 8c82cb7247b3559c5b8f4f2183b7a7571ec34d1b Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:47:00 +0800 Subject: [PATCH 12/13] WIP --- modules/runners/dual.ts | 8 ++--- modules/runners/step.ts | 45 +++++++++++++++------------- tests/deno/single_event_test.ts | 52 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 25 deletions(-) diff --git a/modules/runners/dual.ts b/modules/runners/dual.ts index a8b7226..bdb7f53 100644 --- a/modules/runners/dual.ts +++ b/modules/runners/dual.ts @@ -14,9 +14,7 @@ export class DualRunner { * Create a new instance of the DualRunner. * @param handlers The dual handler profile. */ - constructor( - private handlers: DualEventHandlerSignature[], - ) { + constructor(private handlers: DualEventHandlerSignature[]) { this.handlers = handlers; } @@ -54,6 +52,8 @@ export class DualRunner { * @param args The arguments to pass to the dual handler. */ exec(result: any) { - return new RelayRunner().exec(result, (p) => this.dualExec(p)); + return new RelayRunner().exec(result, (p) => this.dualExec(p), { + async: true, + }); } } diff --git a/modules/runners/step.ts b/modules/runners/step.ts index f3805ca..ad367da 100644 --- a/modules/runners/step.ts +++ b/modules/runners/step.ts @@ -51,10 +51,9 @@ export class StepRunner { const result = new SingleRunner(handler).exec(args); const next = (result: any) => { - const dualResult = new DualRunner(duals).exec(!!result); - return new RelayRunner().exec( - dualResult, - () => this.execByIndex(handlers, duals, args, idx + 1), + const dualResult = new DualRunner(duals).exec(result); + return new RelayRunner().exec(dualResult, () => + this.execByIndex(handlers, duals, args, idx + 1), ); }; @@ -72,8 +71,9 @@ export class StepRunner { for (const p of handlers.filter((e) => !!e.options?.once)) { this.remove(step, p); } - return new SequenceRunner(handlers as GeneralEventHandlerSignature[]) - .exec(args); + return new SequenceRunner( + handlers as GeneralEventHandlerSignature[], + ).exec(args); } /** @@ -84,21 +84,24 @@ export class StepRunner { handlers: EventHandlerSignature[], args?: any[], ) { - const categories = handlers.reduce((y, x) => { - if (x.options?.once) { - y.once.push(x); - } - if (helpers.isDualSignature(x)) { - y.duals.push(x); - } else { - y.handlers.push(x); - } - return y; - }, { - handlers: [] as GeneralEventHandlerSignature[], - duals: [] as DualEventHandlerSignature[], - once: [] as EventHandlerSignature[], - }); + const categories = handlers.reduce( + (y, x) => { + if (x.options?.once) { + y.once.push(x); + } + if (helpers.isDualSignature(x)) { + y.duals.push(x); + } else { + y.handlers.push(x); + } + return y; + }, + { + handlers: [] as GeneralEventHandlerSignature[], + duals: [] as DualEventHandlerSignature[], + once: [] as EventHandlerSignature[], + }, + ); if (!categories.handlers.length) return; for (const p of categories.once) { diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index e11ed7b..197ab74 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -187,6 +187,29 @@ describe("Xevt - conditional event handlers", () => { it('should listen event with "on"', () => { const emitter = new Xevt(); const result: number[] = []; + emitter.on("event", (arg: number) => { + result.push(arg); + return arg % 2 === 0; + }); + + emitter.on("event", { + true: () => { + result.push(100); + }, + false: () => { + result.push(99); + }, + }); + + emitter.emit("event", 1); + emitter.emit("event", 2); + assertEquals(result, [1, 99, 2, 100]); + }); + + it("should executed after async function", async () => { + const emitter = new Xevt(); + const result: number[] = []; + // deno-lint-ignore require-await emitter.on("event", async (arg: number) => { result.push(arg); return arg % 2 === 0; @@ -203,6 +226,35 @@ describe("Xevt - conditional event handlers", () => { emitter.emit("event", 1); emitter.emit("event", 2); + await delay(0); + assertEquals(result, [1, 2, 99, 100]); + }); + + it("should executed after async function - blocking", async () => { + const emitter = new Xevt(); + const result: number[] = []; + // deno-lint-ignore require-await + emitter.on( + "event", + async (arg: number) => { + result.push(arg); + return arg % 2 === 0; + }, + { async: true }, + ); + + emitter.on("event", { + true: () => { + result.push(100); + }, + false: () => { + result.push(99); + }, + }); + + emitter.emit("event", 1); + emitter.emit("event", 2); + await delay(0); assertEquals(result, [1, 99, 2, 100]); }); From 215c3fa65baa2748d328c504f0812a602444484a Mon Sep 17 00:00:00 2001 From: lisez Date: Tue, 28 May 2024 22:54:00 +0800 Subject: [PATCH 13/13] fix --- tests/deno/single_event_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/deno/single_event_test.ts b/tests/deno/single_event_test.ts index 197ab74..100c765 100644 --- a/tests/deno/single_event_test.ts +++ b/tests/deno/single_event_test.ts @@ -233,9 +233,9 @@ describe("Xevt - conditional event handlers", () => { it("should executed after async function - blocking", async () => { const emitter = new Xevt(); const result: number[] = []; - // deno-lint-ignore require-await emitter.on( "event", + // deno-lint-ignore require-await async (arg: number) => { result.push(arg); return arg % 2 === 0;