-
Notifications
You must be signed in to change notification settings - Fork 0
/
callLimit.ts
36 lines (32 loc) · 1.33 KB
/
callLimit.ts
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
import { isFunction, isNumber } from '@utopia-utils/share'
/**
* returns a function that can call the original function the specified number of times.
*
* if call times more than limit, return latest called value
* @param {T} fn - The function to call
* @param [limit] - The number of times the function can be called.
* @returns {Function} new function that calls the original function the specified number of times
* @example
* ```ts
const add = (a: number, b: number) => a + b
const addLimit = callLimit(add, 1)
const res = addLimit(1, 1)
const res2 = addLimit(1, 2)
expect(res).toEqual(2)
expect(res2).toEqual(2) // if call times more than limit, return latest called value
* ```
* @linkcode https://github.com/GreatAuk/utopia-utils/blob/main/packages/core/src/callLimit.ts
*/
export function callLimit<T extends (...args: any[]) => any>(fn: T, limit = 1): (this: ThisParameterType<T>, ...args: Parameters<T>) => ReturnType<T> {
if (!isFunction(fn))
throw new TypeError('fn expected a function')
if (!isNumber(limit))
throw new TypeError('limit expected a number')
let cachedValue: ReturnType<T>
return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
if (--limit >= 0)
cachedValue = fn.apply(this, args)
// if limit < 0, can not call fn again
return cachedValue
}
}