Throttle function doesnt respect delay in certain cases #86

Closed
dcorb opened this Issue Oct 9, 2012 · 4 comments

Comments

2 participants
@dcorb
Contributor

dcorb commented Oct 9, 2012

I found this minor bug when trying to make a demo to visualize throttle and debounce:

http://drupalmotion.com/article/debounce-and-throttle-visual-explanation

In certain cases, due of not clearing the setTimeout, it's leaving a tiny window of time opened, allowing duplicated executions some times.

It doesn't happen so often, but it does happen:

var now = new Date();       
var test = function(a){ console.log(a + (new Date() - now)); }
throttled_test = _.throttle(test, 20);
setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('You should see me only once.');},40);
setTimeout(function(){ throttled_test('You should see me only once.');},40);
@jdalton

This comment has been minimized.

Show comment
Hide comment
@jdalton

jdalton Oct 9, 2012

Member

I think you're seeing the trailing call. See http://lodash.com/docs#throttle.

setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('Hi.');},20);
// => logs "Hi." twice
setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('You should see me only once.');},40);
setTimeout(function(){ throttled_test('You should see me only once.');},40);
// => logs "Hi." once and then "You should see..." twice.

The last call is the trailing call.

Member

jdalton commented Oct 9, 2012

I think you're seeing the trailing call. See http://lodash.com/docs#throttle.

setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('Hi.');},20);
// => logs "Hi." twice
setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('Hi.');},20);
setTimeout(function(){ throttled_test('You should see me only once.');},40);
setTimeout(function(){ throttled_test('You should see me only once.');},40);
// => logs "Hi." once and then "You should see..." twice.

The last call is the trailing call.

@jdalton jdalton closed this Oct 9, 2012

@dcorb

This comment has been minimized.

Show comment
Hide comment
@dcorb

dcorb Oct 9, 2012

Contributor

The text logged is confusing, it was a mistake.Ignore that

The problem is the timing:

Hi.21
You should see me only once.41
You should see me only once.42

The trailing call shouldn't happen just 1ms after. It should be

Hi.21
You should see me only once.41
You should see me only once.61
Contributor

dcorb commented Oct 9, 2012

The text logged is confusing, it was a mistake.Ignore that

The problem is the timing:

Hi.21
You should see me only once.41
You should see me only once.42

The trailing call shouldn't happen just 1ms after. It should be

Hi.21
You should see me only once.41
You should see me only once.61
@jdalton

This comment has been minimized.

Show comment
Hide comment
@jdalton

jdalton Oct 9, 2012

Member

Ah, you're right. Nice visualizations on your post! BTW I had @cowboy help me with Lo-Dash's throttle rewrite ;D

Member

jdalton commented Oct 9, 2012

Ah, you're right. Nice visualizations on your post! BTW I had @cowboy help me with Lo-Dash's throttle rewrite ;D

@dcorb

This comment has been minimized.

Show comment
Hide comment
@dcorb

dcorb Oct 9, 2012

Contributor

Thanks! =) Sorry, it's not that easy to explain.. and it's a edge case.

In the visualization.. because the way is made: "find last span in the row, and replace it with a color", this bug is not going to show (there are 2 replacements of the same span) so you won't see it unless you put really high speed of inserting "spans".

If you want to play with the code it's here:
https://github.com/dcorb/debounce-throttle

Contributor

dcorb commented Oct 9, 2012

Thanks! =) Sorry, it's not that easy to explain.. and it's a edge case.

In the visualization.. because the way is made: "find last span in the row, and replace it with a color", this bug is not going to show (there are 2 replacements of the same span) so you won't see it unless you put really high speed of inserting "spans".

If you want to play with the code it's here:
https://github.com/dcorb/debounce-throttle

jdalton added a commit that referenced this issue Sep 25, 2014

Ensure `_.throttle` clears the timeout when `func` is called. [closes #…
…86]

Former-commit-id: 6f3b777aa247f059d97f965c02323d4ee6ab8464
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment