From 6d152167db8f194e90cdf282100b32ddb5aebd01 Mon Sep 17 00:00:00 2001 From: Coronon <33808743+Coronon@users.noreply.github.com> Date: Sat, 2 Nov 2024 02:56:11 +0100 Subject: [PATCH] fix: don't reuse promise after cancel --- .../useDebounce/useDebounce.svelte.ts | 2 +- .../useDebounce/useDebounce.test.svelte.ts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/runed/src/lib/utilities/useDebounce/useDebounce.svelte.ts b/packages/runed/src/lib/utilities/useDebounce/useDebounce.svelte.ts index 1626bb4..c98cebe 100644 --- a/packages/runed/src/lib/utilities/useDebounce/useDebounce.svelte.ts +++ b/packages/runed/src/lib/utilities/useDebounce/useDebounce.svelte.ts @@ -88,8 +88,8 @@ export function useDebounce( } clearTimeout(context.timeout); - context.timeout = undefined; context.reject("Cancelled"); + context = null; }; Object.defineProperty(debounced, "pending", { diff --git a/packages/runed/src/lib/utilities/useDebounce/useDebounce.test.svelte.ts b/packages/runed/src/lib/utilities/useDebounce/useDebounce.test.svelte.ts index 19254d4..9e7276b 100644 --- a/packages/runed/src/lib/utilities/useDebounce/useDebounce.test.svelte.ts +++ b/packages/runed/src/lib/utilities/useDebounce/useDebounce.test.svelte.ts @@ -29,6 +29,29 @@ describe("useDebounce", () => { expect(fn).not.toHaveBeenCalled(); }); + testWithEffect("Doesn't reuse promise after cancel", async () => { + // Same as above + const fn = vi.fn(); + const debounced = useDebounce(fn, 100); + + expect(fn).not.toHaveBeenCalled(); + debounced().catch(() => {}); + expect(fn).not.toHaveBeenCalled(); + expect(debounced.pending).toBe(true); + debounced.cancel(); + expect(debounced.pending).toBe(false); + await new Promise((resolve) => setTimeout(resolve, 200)); + expect(fn).not.toHaveBeenCalled(); + + // New test + let wasCatchCalled = false; + debounced().catch(() => (wasCatchCalled = true)); + expect(wasCatchCalled).toBe(false); + await new Promise((resolve) => setTimeout(resolve, 110)); + expect(wasCatchCalled).toBe(false); + expect(fn).toHaveBeenCalledTimes(1); + }); + testWithEffect("No race contion with running callback", async () => { let calledNTimes = 0;