I want to throttle my function every 100 milliseconds. In the following code, I expect only 1 and 3 to be printed. But 2 is also printed in the actual result.
function say(what) { console.log(what); } const t = _.throttle(say, 100); setTimeout(() => { t(1); }, 50); setTimeout(() => { t(1); }, 50); setTimeout(() => { t(1); }, 50); setTimeout(() => { t(1); }, 55); setTimeout(() => { t(2); }, 55); setTimeout(() => { t(3); }, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.1/lodash.js"></script>
I have to change the throttle wait time to 500 in order to filter out the 2.
Maybe my understanding of throttle is wrong. Shouldn’t throttle execute the function at most one time per wait period?
Advertisement
Answer
Your understanding of how you are using this throttle setup is not quite right.
To directly answer:
Shouldn’t throttle execute the function at most one time per wait period?
With no options passed in, throttle will execute at the beginning and the end of the wait period (twice), provided the throttled function was called more than once in that period.
At 50ms your first function is called, and ‘throttle’ runs it immediately, also at this time your next f(1) is queued up to be called at 100ms. But then another f(1) is called, and another f(1) and then an f(2), and each new one replaces the last as the function to be called at 100ms (which is the time you’ve passed into throttle). Then over 100ms passes and then f(3) is called more or less when it should be.
If you don’t pass any options into _.throttle
it will immediately call the first function run (at 0ms) and then will call the last function run inside the set time period once that time elapses.
Using @zfrisch’s code as a start:
function say(what) { console.log(what); } const t = _.throttle(say, 100); const TO = (n, i) => setTimeout(() => { t(n); }, i); TO(1, 50); // logged immediately TO(1, 50); TO(1, 50); TO(1, 55); TO(2, 55); // logged at 100ms (as it was the last function attempted)
function say(what) { console.log(what); } const t = _.throttle(say, 100, { leading: false }); const TO = (n, i) => setTimeout(() => { t(n); }, i); TO(1, 50); // not logged at all TO(1, 50); TO(1, 50); TO(1, 55); TO(2, 55); // logged at 100ms (as it was the last function attempted)
function say(what) { console.log(what); } const t = _.throttle(say, 100, { trailing: false }); const TO = (n, i) => setTimeout(() => { t(n); }, i); TO(1, 50); // logged immediately TO(1, 50); TO(1, 50); TO(1, 55); TO(2, 55); // not logged at all