Closures: Debouncing

7/16/2019 · 2 minute read · 1 comment · 1697 views

Orginally posted on

In the previous article in this series, we looked at a practical use of closures called memoization. In this post we’re going to briefly look at closures in action through a debounce function.

A debounce delays the processing of a function for a certain amount of time. It can be very useful with things like forms, buttons, or mouse events–anytime there is a lot of user input possible. It can help prevent rapid fire re-rendering of the DOM by introducing a “cooldown” period, to use gaming terminology.

<!DOCTYPE html>
<html lang="en">

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <button id="button">Click Me</button>

        const debounce = (func, delay) => {
            let inDebounce
            return function () {
                const context = this
                const args = arguments
                inDebounce = setTimeout(() => func.apply(context, args), delay)

        const button = document.getElementById('button')
        button.addEventListener('click', debounce(() => {
            console.log('Hey! It is', new Date().toUTCString())
        }, 3000))

My goal here isn’t to teach you how to write the debounce. There’s plenty of resources (you could literally copy paste a generic debounce function, like I did here). More so, I want you to spot the closure in there and have that “ah-ha” moment. If you want a guide or to get in depth on this function, check out the [source] ( I used.

The key here, from a closure standpoint, is our inDebounce variable. As a closure, returned function “remembers” whether or not it the variable is running a timeout. If we fire it off while it’s still in the timeout, it will clearTimeout, thus restarting it.

Another instance of a closure in action.

Have you guys used debounces before? Are there different variations or use cases where its been super helpful?