fix: debounceAsync.flush and cancel didn't update state

Massimo Melina committed Jun 14, 2022 at 11:29 UTC bf6cd526b2474d40521c45573cb4c70716fcc749
1 file changed +15 -5
server/src/misc.ts
+15 -5
@@ -200,8 +200,11 @@ export function debounceAsync<CB extends (...args: any[]) => Promise<R>, R>(
200 let whoIsWaiting: undefined | any[] // args' array object identifies the pending instance, and incidentally stores args
201 const interceptingWrapper = (...args:any[]) => runningDebouncer = debouncer.apply(null, args)
202 return Object.assign(interceptingWrapper, {
203 - cancel: () => whoIsWaiting = undefined,
204 - flush: () => runningCallback ?? (whoIsWaiting && callback.apply(null, whoIsWaiting)),
203 + cancel: () => {
204 + waitingSince = 0
205 + whoIsWaiting = undefined
206 + },
207 + flush: () => runningCallback ?? exec(),
208 })
209
210 async function debouncer(...args:any[]) {
@@ -216,14 +219,21 @@ export function debounceAsync<CB extends (...args: any[]) => Promise<R>, R>(
219 return void(waitingSince = 0)
220 if (whoIsWaiting !== args) // another fresher call is waiting
221 return runningDebouncer
222 + return await exec()
223 + }
224 +
225 + async function exec() {
226 + if (!whoIsWaiting) return
227 waitingSince = 0
220 - whoIsWaiting = undefined
228 started = Date.now()
229 try {
223 - runningCallback = callback.apply(null, args)
230 + runningCallback = callback.apply(null, whoIsWaiting)
231 return await runningCallback
232 }
226 - finally { runningCallback = undefined }
233 + finally {
234 + whoIsWaiting = undefined
235 + runningCallback = undefined
236 + }
237 }
238 }
239