-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththrottle.js
44 lines (39 loc) · 1.18 KB
/
throttle.js
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
/* eslint-env browser */
// Return a copy of <fn> that can only run once every <period> milliseconds.
export default function throttle(fn, periodMs = 100, runOnFallingEdge){
let fnArmed = true // The first time the input function runs, it won't be throttled
let attemptDuringThisCooldown = false
let cooldownActive = false
const run = ()=>{
fn()
// If the input function runs asyncronously, future attempts will be throttled without having to wait for it to complete
fnArmed = false
attemptDuringThisCooldown = false
ensureTimer()
}
// Start a new cooldown timer if there isn't one running
const ensureTimer = ()=>{
if (!cooldownActive){
setTimeout(()=>{
if (runOnFallingEdge && attemptDuringThisCooldown){
// One final run after the cooldown to ensure that the very latest trigger will guarantee one run.
run()
} else {
fnArmed = true
}
cooldownActive = false
}, periodMs)
cooldownActive = true
}
}
// Attempt to run the input function
const throttledAttempt = ()=>{
if (fnArmed){
run()
} else {
// Remember that we tried to run the function but were throttled
attemptDuringThisCooldown = true
}
}
return throttledAttempt
}