Home > Software design >  Javascript throttle implementation is not delaying
Javascript throttle implementation is not delaying

Time:11-21

this is probably a simple mistake. I'm trying to implement a throttle function (Credit to our man webdevsimplified for quality content: https://blog.webdevsimplified.com/2022-03/debounce-vs-throttle/).

My throttle implementation is not working and I am not sure why. How can I get the throttle working?

<body>
    <script>
        function printHi() {
            console.log("Hi");
        }

        function throttle(cb, delay = 1000) {
            let shouldWait = false
            let waitingArgs
            const timeoutFunc = () => {
                if (waitingArgs == null) {
                    shouldWait = false
                } else {
                    cb(...waitingArgs)
                    waitingArgs = null
                    setTimeout(timeoutFunc, delay)
                }
            }

            return (...args) => {
                console.log("should wait?", shouldWait);
     
                if (shouldWait) {
   // It never goes in here...?
                    waitingArgs = args
                    return
                }

                cb(...args)
                shouldWait = true
                setTimeout(timeoutFunc, delay)
            }
        }
    </script>

    <button onclick="(function () {
        throttle(printHi)();
    })()">Click me</button>

</body>

Consecutive button clicks print to the console:

should wait? false
Hi
should wait? false
Hi
should wait? false
Hi

shouldWait is never printed true, even though it should...

CodePudding user response:

Your original implementation didn't work because shouldWait and waitingArgs were scoped to the function, so every function run had a fresh set of these variables with shouldWait = false.

You might have made this mistake due to the scope differences between var and let, the former was globally scoped if used this way.

Here is my solution, which simply moved the 2 variables out of the function.

function printHi() {
    console.log("Hi");
}

let shouldWait = false
let waitingArgs
function throttle(cb, delay = 1000) {
    const timeoutFunc = () => {
        if (waitingArgs == null) {
            shouldWait = false
        } else {
            cb(...waitingArgs)
            waitingArgs = null
            setTimeout(timeoutFunc, delay)
        }
    }

    return (...args) => {
        console.log("should wait?", shouldWait);

        if (shouldWait) {
// It never goes in here...?
            waitingArgs = args
            return
        }

        cb(...args)
        shouldWait = true
        setTimeout(timeoutFunc, delay)
    }
}
<body>
    <button onclick="(function () {
        throttle(printHi)();
    })()">Click me</button>
</body>

  • Related