From 942057eb2383178d6d71c04a5d91e7fbf656da1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Thu, 15 Aug 2024 05:50:28 +0200 Subject: [PATCH] feat(debounce): add `leading` option (#128) --- docs/curry/debounce.mdx | 9 +++++++++ src/curry/debounce.ts | 18 +++++++++++++++++- tests/curry/debounce.test.ts | 8 ++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/docs/curry/debounce.mdx b/docs/curry/debounce.mdx index d79b9c16..e25e2f2c 100644 --- a/docs/curry/debounce.mdx +++ b/docs/curry/debounce.mdx @@ -32,6 +32,15 @@ debounce Invocations: x x x x - - - - - - - - x x x x x x x x x x - - - - - - - Source Invocations: - - - - - - - - - - x - - - - - - - - - - - - - - - - - x - - - - - ``` +The `leading` option decides whether the source function is called on the first +invocation of the throttle function or not. + +```sh +Time: 0ms - - - - 100ms - - - - 200ms - - - - 300ms - - - - 400ms - - - - +debounce Invocations: x x x x - - - - - - - - x x x x x x x x x x - - - - - - - - - - - - +Source Invocations: x - - - - - - - - - x - - - - - - - - - - - - - - - - - x - - - - - +``` + ### Cancel The function returned by `debounce` has a `cancel` method that when called will permanently stop the source function from being debounced. diff --git a/src/curry/debounce.ts b/src/curry/debounce.ts index a09f815e..70614c2a 100644 --- a/src/curry/debounce.ts +++ b/src/curry/debounce.ts @@ -37,7 +37,19 @@ export type DebounceFunction = { * ``` */ export function debounce( - { delay }: { delay: number }, + { + delay, + leading = false, + }: { + delay: number + /** + * Decides whether the source function is called on the first + * invocation of the throttle function or not + * + * @default false + */ + leading?: boolean + }, func: (...args: TArgs) => any, ): DebounceFunction { let timer: unknown = undefined @@ -50,6 +62,10 @@ export function debounce( active && func(...args) timer = undefined }, delay) + if (leading) { + func(...args) + leading = false + } } else { func(...args) } diff --git a/tests/curry/debounce.test.ts b/tests/curry/debounce.test.ts index 1c0d2bd5..7d9c8192 100644 --- a/tests/curry/debounce.test.ts +++ b/tests/curry/debounce.test.ts @@ -75,4 +75,12 @@ describe('debounce', () => { vi.advanceTimersByTime(delay + 10) expect(mockFunc).toHaveBeenCalledTimes(0) }) + + test('executes the function immediately on the first invocation when `leading` is `true`', async () => { + func = _.debounce({ delay: delay, leading: true }, mockFunc) + runFunc3Times() + expect(mockFunc).toHaveBeenCalledTimes(1) + vi.advanceTimersByTime(delay + 10) + expect(mockFunc).toHaveBeenCalledTimes(2) + }) })