Play with the controls to see how the code works. All code is present in the page, but some scrollback may be necessary to grok everything.
# debouncing / throttling
2 min read
Treat repeated events happening across short periods of time as a single event with debouncing and throttling.
# setTimeout() / clearTimeout()
const seconds = n => n * 1000
const log = msg =>
console.log(`hello, ${msg}`)
let id
function run() {
id = setTimeout(
log,
seconds(1),
'world'
)
}
function clear() {
clearTimeout(id)
}
# runAfter()
const clear = runAfter(
seconds(1),
() => log('world')
)
function runAfter(ms, fn, ...args) {
const id = setTimeout(fn, ms, ...args)
return () => clearTimeout(id)
}
# RunAfter()
const [run, clear] = RunAfter(
seconds(1),
() => log('world')
)
function RunAfter(ms, fn) {
let id
const clear = () => clearTimeout(id)
const run = (...args) => {
id = setTimeout(fn, ms, ...args)
}
return [run, clear]
}
# makeDebouncer()
const greetings = () =>
console.log('hello, world')
const [debounce] =
makeDebouncer(1000, greetings)
function makeDebouncer(ms, fn) {
const [run, clear] = RunAfter(ms, fn)
const debouncer = (...args) => (
clear(), run(...args)
)
return [debouncer, clear]
}
# cancel()
const [debounce, cancel] =
makeDebouncer(seconds(1), greetings)
# makeThrottler()
const greetings = () =>
console.log('hello, world')
const [throttle] =
makeThrottler(1000, greetings)
function makeThrottler(ms, fn) {
let canRun = true
const [throttle, clear] =
RunAfter(ms, reset)
return [throttler, reset]
function throttler(...args) {
if (!canRun) return
canRun = false
throttle()
fn(...args)
}
function reset() {
clear()
canRun = true
}
}