Skip to content

Commit 3de5f46

Browse files
committed
Merge branch 'search' of github.com:techdiary-dev/techdiary.dev into search
2 parents 3a76cbe + c6e10af commit 3de5f46

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/utils/curry.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
export type DebounceFunction<TArgs extends any[]> = {
2+
(...args: TArgs): void;
3+
/**
4+
* Cancels the debounced function
5+
*/
6+
cancel(): void;
7+
/**
8+
* Checks if there is any invocation debounced
9+
*/
10+
isPending(): boolean;
11+
/**
12+
* Runs the debounced function immediately
13+
*/
14+
flush(...args: TArgs): void;
15+
};
16+
17+
/**
18+
* Given a delay and a function returns a new function
19+
* that will only call the source function after delay
20+
* milliseconds have passed without any invocations.
21+
*
22+
* The debounce function comes with a `cancel` method
23+
* to cancel delayed `func` invocations and a `flush`
24+
* method to invoke them immediately
25+
*/
26+
export const debounce = <TArgs extends any[]>(
27+
func: (...args: TArgs) => any,
28+
{ delay = 500 }: { delay: number },
29+
) => {
30+
let timer: ReturnType<typeof setTimeout> | undefined = undefined;
31+
let active = true;
32+
33+
const debounced: DebounceFunction<TArgs> = (...args: TArgs) => {
34+
if (active) {
35+
clearTimeout(timer);
36+
timer = setTimeout(() => {
37+
active && func(...args);
38+
timer = undefined;
39+
}, delay);
40+
} else {
41+
func(...args);
42+
}
43+
};
44+
debounced.isPending = () => {
45+
return timer !== undefined;
46+
};
47+
debounced.cancel = () => {
48+
active = false;
49+
};
50+
debounced.flush = (...args: TArgs) => func(...args);
51+
52+
return debounced;
53+
};

0 commit comments

Comments
 (0)