Reputation: 437
Is a function:
var f = function(a) { console.log(a) };
function throttle(func, ms) {
var stop = false, savedThis, savedArgs;
return function wrapper() {
if(stop) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments)
stop = true;
setTimeout(function() {
stop = false;
if(savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
};
}
// brake function to once every 1000 ms
var f1000 = throttle(f, 1000);
f1000(1); // print 1
f1000(2); // (brakes, less than 1000ms)
f1000(3); // (brakes, less than 1000ms)
The first call f1000 (1)
displays 1. f1000 (2)
, the second call does not work, but it will keep in savedAggs
link to the arguments of the second call. The third launch also does not work, but it will overwrite the link to the arguments of the third call. Through 1000 ms setTimeout
cause an anonymous function, the variable will stop
within the meaning of the false
. Condition of work, and the wrapper
will be called recursively. But then I can not understand what's going on? When this code works: savedArgs = savedThis = null;
?
Upvotes: 1
Views: 68
Reputation: 664548
The function is a bit incomprehensible, yes. Its job is to throttle the rate of invocations to at most one per 1000 ms - however if they occur more frequent, it will also repeat the last invocation as soon as the timeout has finished.
It might better be written
function throttle(func, ms) {
var stop = false, savedThis, savedArgs;
function invoke() {
stop = true; // the last invocation will have been less than `ms` ago
func.apply(savedThis, savedArgs);
savedThis = savedArgs = null;
setTimeout(function() {
stop = false; // the timeout is over, start accepting new invocations
if (savedArgs) // there has been at least one invocation during
// the current timeout
invoke(); // let's repeat that
}, ms);
}
return function wrapper() {
savedArgs = arguments;
savedThis = this;
if (stop)
return;
else
invoke();
};
}
Upvotes: 2