Debouncing waits until the calls stop coming for a while, then runs once. Perfect for search fields and resize handlers.
function debounce(fn, wait = 200) {
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => fn(...args), wait)
}
}
Use it like this:
const search = debounce((query) => fetchResults(query), 300)
input.addEventListener('input', (event) => search(event.target.value))
Every keystroke resets the timer, so fetchResults runs 300 ms after the last one.