Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 1x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { isUndefined } from '../is'
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. The throttled function comes with a `cancel`
* method to cancel delayed `func` invocations.
*
* @param func The function to throttle
* @param wait The number of milliseconds to throttle invocations to
* @returns Returns the new throttled function
*
* {@link https://lodash.com/docs#throttle}
*/
export function throttle<T extends (...args: any[]) => any>(
func: T,
wait: number = 0,
): (...args: Parameters<T>) => void {
let timeoutId: ReturnType<typeof setTimeout> | undefined
let lastArgs: Parameters<T> | undefined
let lastCallTime: number | undefined
return function throttled(this: any, ...args: Parameters<T>): void {
let time = Date.now()
if (isUndefined(lastCallTime)) {
lastCallTime = time
func.apply(this, args)
}
else {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => {
time = Date.now()
Eif ((time - lastCallTime!) >= wait) {
func.apply(this, lastArgs!)
lastCallTime = time
timeoutId = undefined
lastArgs = undefined
}
}, wait)
lastArgs = args
}
}
}
Eif (import.meta.vitest) {
const { test, expect, vi } = import.meta.vitest
test('throttle', async () => {
vi.useFakeTimers()
const fn = vi.fn()
const throttled = throttle(fn, 100)
expect(fn).not.toHaveBeenCalled()
throttled()
expect(fn).toHaveBeenCalledTimes(1)
throttled()
vi.advanceTimersByTime(100)
expect(fn).toHaveBeenCalledTimes(2)
vi.useRealTimers()
})
}
|