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>
