-
Notifications
You must be signed in to change notification settings - Fork 15
/
index.ts
68 lines (63 loc) · 1.52 KB
/
index.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
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
68
export interface ThrottleOptions {
/**
* Fire immediately on the first call.
*/
start?: boolean
/**
* Fire as soon as `wait` has passed.
*/
middle?: boolean
/**
* Cancel after the first successful call.
*/
once?: boolean
}
interface Throttler<T extends unknown[]> {
(...args: T): void
cancel(): void
}
export function throttle<T extends unknown[]>(
callback: (...args: T) => unknown,
wait = 0,
{start = true, middle = true, once = false}: ThrottleOptions = {}
): Throttler<T> {
let innerStart = start
let last = 0
let timer: ReturnType<typeof setTimeout>
let cancelled = false
function fn(this: unknown, ...args: T) {
if (cancelled) return
const delta = Date.now() - last
last = Date.now()
if (start && middle && delta >= wait) {
innerStart = true
}
if (innerStart) {
innerStart = false
callback.apply(this, args)
if (once) fn.cancel()
} else if ((middle && delta < wait) || !middle) {
clearTimeout(timer)
timer = setTimeout(
() => {
last = Date.now()
callback.apply(this, args)
if (once) fn.cancel()
},
!middle ? wait : wait - delta
)
}
}
fn.cancel = () => {
clearTimeout(timer)
cancelled = true
}
return fn
}
export function debounce<T extends unknown[]>(
callback: (...args: T) => unknown,
wait = 0,
{start = false, middle = false, once = false}: ThrottleOptions = {}
): Throttler<T> {
return throttle(callback, wait, {start, middle, once})
}