Skip to content

Commit 39909c4

Browse files
webNeatTkDodo
andauthored
perf(asyncThrottle): Improve performance (TanStack#7224)
Co-authored-by: Dominik Dorfmeister <[email protected]>
1 parent e03cc3a commit 39909c4

File tree

1 file changed

+24
-37
lines changed

1 file changed

+24
-37
lines changed

packages/query-async-storage-persister/src/asyncThrottle.ts

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,33 @@ export function asyncThrottle<TArgs extends ReadonlyArray<unknown>>(
1111
) {
1212
if (typeof func !== 'function') throw new Error('argument is not function.')
1313

14-
let running = false
15-
let lastTime = 0
16-
let timeout: ReturnType<typeof setTimeout>
17-
let currentArgs: TArgs | null = null
14+
let nextExecutionTime = 0
15+
let lastArgs = null
16+
let isExecuting = false
17+
let isScheduled = false
1818

19-
const execFunc = async () => {
20-
if (currentArgs) {
21-
const args = currentArgs
22-
currentArgs = null
19+
return async (...args: TArgs) => {
20+
lastArgs = args
21+
if (isScheduled) return
22+
isScheduled = true
23+
while (isExecuting) {
24+
await new Promise((done) => setTimeout(done, interval))
25+
}
26+
while (Date.now() < nextExecutionTime) {
27+
await new Promise((done) =>
28+
setTimeout(done, nextExecutionTime - Date.now()),
29+
)
30+
}
31+
isScheduled = false
32+
isExecuting = true
33+
try {
34+
await func(...lastArgs)
35+
} catch (error) {
2336
try {
24-
running = true
25-
await func(...args)
26-
} catch (error) {
2737
onError(error)
28-
} finally {
29-
lastTime = Date.now() // this line must after 'func' executed to avoid two 'func' running in concurrent.
30-
running = false
31-
}
32-
}
33-
}
34-
35-
const delayFunc = async () => {
36-
clearTimeout(timeout)
37-
timeout = setTimeout(() => {
38-
if (running) {
39-
delayFunc() // Will come here when 'func' execution time is greater than the interval.
40-
} else {
41-
execFunc()
42-
}
43-
}, interval)
44-
}
45-
46-
return (...args: TArgs) => {
47-
currentArgs = args
48-
49-
const tooSoon = Date.now() - lastTime < interval
50-
if (running || tooSoon) {
51-
delayFunc()
52-
} else {
53-
execFunc()
38+
} catch {}
5439
}
40+
nextExecutionTime = Date.now() + interval
41+
isExecuting = false
5542
}
5643
}

0 commit comments

Comments
 (0)