ðŸŠī\zansh.in\js

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
}
}

Google it:

ðŸŒļ clearTimeout 🌚 closures 🌷 destructuring assignment ðŸŒŧ expression statement 🌞 function composition ðŸŒđ high-order functions 💐 hoisting ðŸŒļ setTimeout 🌚 spread rest