-
Notifications
You must be signed in to change notification settings - Fork 0
/
timing.ts
89 lines (83 loc) · 2.46 KB
/
timing.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { NoValue } from './data.ts'
export function next_tick(f: () => any) {
return setTimeout(f, 0)
}
/** throttle a function, so that multiple calls execute at most once per **t** milliseconds */
export function throttle<T>(f: (x: T) => any, t: number): (x: T) => any {
let nextValue: T | typeof NoValue = NoValue;
let id: ReturnType<typeof setTimeout> | undefined;
return (function throttle(x: T): void {
if (id)
nextValue = x;
else {
nextValue = NoValue;
id = setTimeout(() => {
if (nextValue !== NoValue)
f(nextValue as T)
id = undefined
}, t)
f(x)
}
})
}
/** debounce a function, so that multiple calls execute only once after **t** milliseconds of delay */
export function debounce<T>(f: (x: T) => any, t: number): (x: T) => void {
let id: ReturnType<typeof setTimeout> | undefined;
return (function debounce(x: T): void {
if (id) {
clearTimeout(id)
id = undefined
}
id = setTimeout(() => {
f(x)
id = undefined
}, t)
})
}
/** debounce a function, so that multiple calls execute only once when time is available */
export function microtask<T extends Array<any>>(f: (...xs: T) => void) {
let running: boolean = false;
let args: T | never[] = [];
return function microtask(...xs: T): void {
if (running) {
args = xs
return
}
running = true
args = xs
queueMicrotask(() => {
f(...args as T)
args = []
running = false
})
}
}
export function on_next_frame<T extends Array<any>>(f: (...xs: T) => void) {
let running: boolean = false;
let args: T | never[] = [];
return function on_next_frame(...xs: T): void {
if (running) {
args = xs
return
}
running = true
args = xs
requestAnimationFrame(() => {
f(...args as T)
args = []
running = false
})
}
}
export function once<T extends Array<any>>(f: (...xs: T) => void | Promise<void>) {
let running: boolean = false;
return function once(...xs: T): void {
if (running) return
running = true
const x = f(...xs)
if (x instanceof Promise)
x.finally(() => running = false)
else
running = false;
}
}