Skip to content

Commit

Permalink
fix(debounceFilter): invoke on maxWait with the latest invoker (#4497)
Browse files Browse the repository at this point in the history
Co-authored-by: Robin Kehl <[email protected]>
Co-authored-by: OrbisK <[email protected]>
  • Loading branch information
3 people authored Jan 22, 2025
1 parent b6947f7 commit 48e0a2e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
5 changes: 4 additions & 1 deletion packages/shared/utils/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export function debounceFilter(ms: MaybeRefOrGetter<number>, options: DebounceFi
lastRejector = noop
}

let lastInvoker: () => void

const filter: EventFilter = (invoke) => {
const duration = toValue(ms)
const maxDuration = toValue(options.maxWait)
Expand All @@ -90,13 +92,14 @@ export function debounceFilter(ms: MaybeRefOrGetter<number>, options: DebounceFi

return new Promise((resolve, reject) => {
lastRejector = options.rejectOnCancel ? reject : resolve
lastInvoker = invoke
// Create the maxTimer. Clears the regular timer on invoke
if (maxDuration && !maxTimer) {
maxTimer = setTimeout(() => {
if (timer)
_clearTimeout(timer)
maxTimer = null
resolve(invoke())
resolve(lastInvoker())
}, maxDuration)
}

Expand Down
29 changes: 28 additions & 1 deletion packages/shared/watchDebounced/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,33 @@ describe('watchDebounced', () => {
num.value = 5
await vi.advanceTimersByTimeAsync(75)
expect(cb).toHaveBeenCalledTimes(2)
expect(cb).toHaveBeenCalledWith(4, 2, expect.anything())
expect(cb).toHaveBeenCalledWith(5, 4, expect.anything())
})

it('should work with constant changes over multiple maxWaits', async () => {
vi.useFakeTimers()
const num = ref(0)
const cb = vi.fn()

const constantUpdateOverTime = async (ms: number) => {
for (let i = 0; i < ms; i++) {
num.value += 1
await vi.advanceTimersByTimeAsync(1)
}
}
watchDebounced(num, cb, { debounce: 10, maxWait: 50 })
expect(cb).toHaveBeenCalledTimes(0)
await constantUpdateOverTime(49)
expect(cb).toHaveBeenCalledTimes(0)
await constantUpdateOverTime(1)
expect(cb).toHaveBeenCalledTimes(1)
await constantUpdateOverTime(50)
expect(cb).toHaveBeenCalledTimes(2)
await constantUpdateOverTime(50)

expect(cb).toHaveBeenCalledTimes(3)
expect(cb.mock.calls[0][0]).toBe(50)
expect(cb.mock.calls[1][0]).toBe(100)
expect(cb.mock.calls[2][0]).toBe(150)
})
})

0 comments on commit 48e0a2e

Please sign in to comment.