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>