Skip to content

Commit 73a20c4

Browse files
committed
use asyncThrottle instead of sync throttle
1 parent 9cf8bd4 commit 73a20c4

File tree

1 file changed

+38
-14
lines changed
  • src/createAsyncStoragePersistor-experimental

1 file changed

+38
-14
lines changed

src/createAsyncStoragePersistor-experimental/index.ts

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ export const asyncStoragePersistor = ({
2020
throttleTime,
2121
}: CreateAsyncStoragePersistorOptions) => {
2222
return {
23-
persistClient: throttle(
23+
persistClient: asyncThrottle(
2424
persistedClient => storage.setItem(key, JSON.stringify(persistedClient)),
25-
throttleTime
25+
{ interval: throttleTime }
2626
),
2727
restoreClient: async () => {
2828
const cacheString = await storage.getItem(key)
@@ -37,18 +37,42 @@ export const asyncStoragePersistor = ({
3737
}
3838
}
3939

40-
function throttle<TArgs extends any[]>(
41-
func: (...args: TArgs) => any,
42-
wait = 100
40+
function asyncThrottle<T>(
41+
func: (...args: ReadonlyArray<unknown>) => Promise<T>,
42+
{ interval = 100, limit = 1 }: { interval?: number; limit?: number } = {}
4343
) {
44-
let timer: number | null = null
44+
if (typeof func !== 'function') throw new Error('argument is not function.')
45+
const running = { current: false }
46+
let lastTime = 0
47+
let timeout: number
48+
const queue: Array<any[]> = []
49+
return (...args: any) =>
50+
(async () => {
51+
if (running) {
52+
lastTime = Date.now()
53+
if (queue.length > limit) {
54+
queue.shift()
55+
}
4556

46-
return function (...args: TArgs) {
47-
if (timer === null) {
48-
timer = setTimeout(() => {
49-
func(...args)
50-
timer = null
51-
}, wait)
52-
}
53-
}
57+
queue.push(args)
58+
clearTimeout(timeout)
59+
}
60+
if (Date.now() - lastTime > interval) {
61+
running.current = true
62+
await func(...args)
63+
lastTime = Date.now()
64+
running.current = false
65+
} else {
66+
if (queue.length > 0) {
67+
const lastArgs = queue[queue.length - 1]!
68+
timeout = setTimeout(async () => {
69+
if (!running.current) {
70+
running.current = true
71+
await func(...lastArgs)
72+
running.current = false
73+
}
74+
}, interval)
75+
}
76+
}
77+
})()
5478
}

0 commit comments

Comments
 (0)