( fn: (this: ThrottledFunction<T>, ...args: T) => void, timeframe: number | ((previousDuration: number) => number), options?: ThrottleOptions, )
| 101 | */ |
| 102 | // deno-lint-ignore no-explicit-any |
| 103 | export function throttle<T extends Array<any>>( |
| 104 | fn: (this: ThrottledFunction<T>, ...args: T) => void, |
| 105 | timeframe: number | ((previousDuration: number) => number), |
| 106 | options?: ThrottleOptions, |
| 107 | ): ThrottledFunction<T> { |
| 108 | const ensureLast = Boolean(options?.ensureLastCall); |
| 109 | let timeout: ReturnType<typeof setTimeout> | undefined; |
| 110 | |
| 111 | let lastExecution = -Infinity; |
| 112 | let flush: (() => void) | null = null; |
| 113 | let throttlingAsync = false; |
| 114 | |
| 115 | let tf = typeof timeframe === "function" ? 0 : timeframe; |
| 116 | |
| 117 | const throttled = ((...args: T) => { |
| 118 | flush = () => { |
| 119 | const start = Date.now(); |
| 120 | let result: unknown; |
| 121 | const done = () => { |
| 122 | throttlingAsync = false; |
| 123 | lastExecution = Date.now(); |
| 124 | if (typeof timeframe === "function") { |
| 125 | tf = timeframe(lastExecution - start); |
| 126 | } |
| 127 | }; |
| 128 | try { |
| 129 | clearTimeout(timeout); |
| 130 | result = fn.call(throttled, ...args); |
| 131 | } finally { |
| 132 | if (isPromiseLike(result)) { |
| 133 | throttlingAsync = true; |
| 134 | Promise.resolve(result).finally(done); |
| 135 | } else { |
| 136 | done(); |
| 137 | } |
| 138 | flush = null; |
| 139 | } |
| 140 | }; |
| 141 | if (throttled.throttling) { |
| 142 | if (ensureLast) { |
| 143 | clearTimeout(timeout); |
| 144 | timeout = setTimeout(() => flush?.(), tf); |
| 145 | } |
| 146 | return; |
| 147 | } |
| 148 | flush?.(); |
| 149 | }) as ThrottledFunction<T>; |
| 150 | |
| 151 | throttled.clear = () => { |
| 152 | throttlingAsync = false; |
| 153 | lastExecution = -Infinity; |
| 154 | }; |
| 155 | |
| 156 | throttled.flush = () => { |
| 157 | flush?.(); |
| 158 | }; |
| 159 | |
| 160 | Object.defineProperties(throttled, { |
no test coverage detected