Reputation: 135
I want to use a JS Throttle. But i'm struggeling to get it work correctly.
I tried the code from this article: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf
But the Throttle does not work as intended, since everytime i click on the button, one "|" is added to the div. No clicks were discarded.
where is the misstake?
function foo() {
$("#respond").append("|");
}
const throttle = (func, limit) => {
let inThrottle
return function() {
const args = arguments
const context = this
if (!inThrottle) {
func.apply(context, args)
inThrottle = true
setTimeout(() => inThrottle = false, limit)
}
}
}
var onClick = function() {
throttle(foo(), 50000);
};
$('#button').click(onClick);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="button" value="Click Me" />
<div id="respond"></div>
Upvotes: 8
Views: 8371
Reputation: 5797
In order for throttle(func, limit)
to work, there can only be one instance of its product.
The problem is that the onClick
function in your example creates a new instance each time it is called.
This makes the underlying inThrottle
variable meaningless, as a new copy is created for each click.
The solution is to call one single instance the product of throttle(foo, 50000)
directly.
Also, foo
itself should be passed (not its product).
See below for a practical example, as well as closures and scope for more info.
// Foo.
const foo = (...args) => {
$("#respond").append("|");
}
// Throttle.
const throttle = (func, limit) => {
let inThrottle
return (...args) => {
if (!inThrottle) {
func(...args)
inThrottle = setTimeout(() => inThrottle = false, limit)
}
}
}
// On Click.
const onClick = throttle(foo, 1000)
// Button - Click.
$('#button').click(onClick);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="button" value="Click Me" />
<div id="respond"></div>
Upvotes: 9
Reputation: 169
I know the question is old.
I made a small snippet. I think it should qualify as a simple way to throttle a function. This will guarantee a call every wait milliseconds.
function throttle( fn, wait ){
let lastCall = 0;
return function(){
if( Date.now() - lastCall > wait ){
lastCall = Date.now()
fn()
}
}
}
var counter = 0
var count = () => document.querySelector("#count").textContent = ++counter
window.addEventListener('scroll', throttle( count, 1000 ) )
body{
height: 2000px;
}
<h1 id='count'>
0
</h1>
Upvotes: 4
Reputation: 6075
Your onClick is creating a new throttled function on every invoke. You have to ensure that is only throttled once
var onClick = function() {
throttle(foo(), 50000);
};
// TO
var onClick = throttle(foo, 50000);
Upvotes: 2