Closures & Scopemedium

Implement throttle(fn, delay)

Write a `throttle` function that ensures `fn` is called at most once per `delay` ms window, with a leading call and a trailing call guaranteed.

Asked at Google, Amazon, Uber, TikTok

#closures#timers#performance

Answer

function throttle(fn, delay) {
  let lastCall = 0
  let timer = null

  return function (...args) {
    const remaining = delay - (Date.now() - lastCall)
    clearTimeout(timer)

    if (remaining <= 0) {
      fn.apply(this, args)
      lastCall = Date.now()
    } else {
      // trailing call — always fire with the latest args
      timer = setTimeout(() => {
        fn.apply(this, args)
        lastCall = Date.now()
      }, remaining)
    }
  }
}

// Usage
const onScroll = throttle(() => {
  console.log('sync virtualized rows')
}, 100)
window.addEventListener('scroll', onScroll)

Source: frontendinterviewhandbook.com

Practise more Closures & Scope questions →