From b171cb7f1367a2058f01d4edfa4d8974b060d247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Sun, 21 Jul 2024 13:46:03 +0200 Subject: [PATCH 1/4] add `leading` option for `debounce` --- docs/curry/debounce.mdx | 9 +++++++++ src/curry/debounce.ts | 6 +++++- tests/curry/debounce.test.ts | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/curry/debounce.mdx b/docs/curry/debounce.mdx index e2bd9ddb..26320460 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..6cbd0c39 100644 --- a/src/curry/debounce.ts +++ b/src/curry/debounce.ts @@ -37,7 +37,7 @@ export type DebounceFunction = { * ``` */ export function debounce( - { delay }: { delay: number }, + { delay, leading = false }: { delay: number; leading?: boolean }, func: (...args: TArgs) => any, ): DebounceFunction { let timer: unknown = undefined @@ -50,6 +50,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..1e3c58da 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 of the debounce function when set `leading` to true', async () => { + func = _.debounce({ delay: delay, leading: true }, mockFunc) + runFunc3Times() + expect(mockFunc).toHaveBeenCalledTimes(1) + vi.advanceTimersByTime(delay + 10) + expect(mockFunc).toHaveBeenCalledTimes(2) + }) }) From 862ac0d83a4abfec5e1df3b7abf2e042a91730ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Sun, 11 Aug 2024 18:10:57 +0200 Subject: [PATCH 2/4] chore: add jsdoc suggested by @MarlonPassos-git --- src/curry/debounce.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/curry/debounce.ts b/src/curry/debounce.ts index 6cbd0c39..ffa9fe91 100644 --- a/src/curry/debounce.ts +++ b/src/curry/debounce.ts @@ -37,7 +37,16 @@ export type DebounceFunction = { * ``` */ export function debounce( - { delay, leading = false }: { delay: number; leading?: boolean }, + { 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 From 06c5b74d2862ed274f50483ffc545d9dd6c02208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Sun, 11 Aug 2024 18:12:30 +0200 Subject: [PATCH 3/4] fix: wording --- tests/curry/debounce.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/curry/debounce.test.ts b/tests/curry/debounce.test.ts index 1e3c58da..7d9c8192 100644 --- a/tests/curry/debounce.test.ts +++ b/tests/curry/debounce.test.ts @@ -76,7 +76,7 @@ describe('debounce', () => { expect(mockFunc).toHaveBeenCalledTimes(0) }) - test('executes the function immediately on the first invocation of the debounce function when set `leading` to true', async () => { + 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) From 718ded5ef260d7c6f21a14dbfebd4738573a8e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Sun, 11 Aug 2024 18:16:34 +0200 Subject: [PATCH 4/4] style: format --- src/curry/debounce.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/curry/debounce.ts b/src/curry/debounce.ts index ffa9fe91..70614c2a 100644 --- a/src/curry/debounce.ts +++ b/src/curry/debounce.ts @@ -37,12 +37,15 @@ export type DebounceFunction = { * ``` */ export function debounce( - { delay, leading = false }: { - 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