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() }) } |