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;