Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/util/async-debounce-throttle.ts
1447 views
1
/*
2
I couldn't find a good npm library to debounce an async function, but this
3
code from GPT-4o works well.
4
5
AUTHOR: GPT-4o
6
7
*/
8
9
/*
10
The regular lodash debounce function does not return a promise, but you
11
can create your own wrapper to handle this.
12
13
### Key Points:
14
15
1. **Promise Wrapping**: Use a promise to ensure `await bar()` doesn't resolve until
16
after the actual function executes.
17
18
2. **Queue Maintenance**: Utilize a queue (`resolveQueue`) to store and resolve
19
promises after the debounced function executes.
20
21
3. **Custom Debounce Wrapper**: The `debouncePromise` function handles the
22
integration of promises with `lodash` debounce.
23
*/
24
25
import {
26
debounce,
27
throttle,
28
type DebounceSettings,
29
type ThrottleSettings,
30
} from "lodash";
31
32
export function asyncDebounce(
33
func: (...args: any[]) => Promise<any>,
34
wait: number,
35
options?: DebounceSettings,
36
): (...args: any[]) => Promise<any> {
37
let resolveQueue: Array<() => void> = [];
38
39
const debounced = debounce(
40
async (...args: any[]) => {
41
await func(...args);
42
// Resolve all stored promises
43
resolveQueue.forEach((resolve) => resolve());
44
resolveQueue = [];
45
},
46
wait,
47
options,
48
);
49
50
return (...args: any[]) =>
51
new Promise<void>((resolve) => {
52
resolveQueue.push(resolve);
53
debounced(...args);
54
});
55
}
56
57
export function asyncThrottle(
58
func: (...args: any[]) => Promise<any>,
59
wait: number,
60
options?: ThrottleSettings,
61
): (...args: any[]) => Promise<any> {
62
let resolveQueue: Array<() => void> = [];
63
64
const throttled = throttle(
65
async (...args: any[]) => {
66
await func(...args);
67
// Resolve all stored promises
68
resolveQueue.forEach((resolve) => resolve());
69
resolveQueue = [];
70
},
71
wait,
72
options,
73
);
74
75
return (...args: any[]) =>
76
new Promise<void>((resolve) => {
77
resolveQueue.push(resolve);
78
throttled(...args);
79
});
80
}
81
82