Throttle & debounce functions
Asked Answered
W

3

9

I am a bit uncertain with the concepts of throttle and debounce functions.

As I get it:

we debounce a function that should be called after a certain event has happened. It is used in events like drag, keyup, etc. with the purpose of not firing all the time the event gets fired but instead when the series of events is done. Typically after a whole word has been typed, or a drag or resize sequence has ended.

we throttle a function that should fire while a series of events is happening, but when we want to control the amount of times it gets called. Like in a drag movement we want the function to be called only every x pixels of distance, or only every 100ms, and not every time the event is fired. So the throttle function is called while the series of events is happening, just fewer times.

Question:

is this a correct perception of what these functions are and their purpose? are there other features that distinguish them?

Warpath answered 13/5, 2015 at 18:38 Comment(3)
Ben Alman's post on throttle vs debounce has some useful visualizations.Vasodilator
@Vasodilator interesting reading. Thank you.Warpath
Possible duplicate of Difference Between throttling and debouncing a functionNalda
C
3

Yes, that's a good synopsis of the differences.

However, you might want to emphasize that these methods don't actually alter the functions they are called upon. They just create a new function (with an identity, to which the rate limiting behaviour is bound) that can be called as often as necessary, and internally relays the calls to the debounced or throttled function.

Costive answered 13/5, 2015 at 18:46 Comment(4)
Thank you Bergi. Is there a implicit rule/convention that the scope of the function should be passed into the debounce or throttle function?Warpath
What do you mean by "scope"? The scope of the debounced/throttled is implicitly passed to those functions (but cannot be accessed) as it is bound by closure.Costive
I mean like in the underscore debounce function, there is a context being passed in .apply(context, arguments) when the function is finally called. Should one expect that from a debounce function, as a convention/rule?Warpath
No, that's just a convenience parameter (they used apply anyway) and not inherent to throttling/debouncing behaviour. You could just as well have to use .bind() on the throttled/debounced function, and I'm certain that with ES6 arrow functions we will see such things fewer. But you're right, it's an underscorejs convention that all callback-taking functions also take a this context.Costive
C
4

For short:

throttle is designed to call function in certain interval during constant call. Like: window.scroll. debounce is designed to call function only once during one certain time. not matter how many time it called. Like: submit button click. Here is the example:

//http://jsfiddle.net/1dr00xbn/

you can see the difference.

Carrew answered 4/6, 2015 at 10:27 Comment(1)
This is very short and very clear to understand.Meadow
C
3

Yes, that's a good synopsis of the differences.

However, you might want to emphasize that these methods don't actually alter the functions they are called upon. They just create a new function (with an identity, to which the rate limiting behaviour is bound) that can be called as often as necessary, and internally relays the calls to the debounced or throttled function.

Costive answered 13/5, 2015 at 18:46 Comment(4)
Thank you Bergi. Is there a implicit rule/convention that the scope of the function should be passed into the debounce or throttle function?Warpath
What do you mean by "scope"? The scope of the debounced/throttled is implicitly passed to those functions (but cannot be accessed) as it is bound by closure.Costive
I mean like in the underscore debounce function, there is a context being passed in .apply(context, arguments) when the function is finally called. Should one expect that from a debounce function, as a convention/rule?Warpath
No, that's just a convenience parameter (they used apply anyway) and not inherent to throttling/debouncing behaviour. You could just as well have to use .bind() on the throttled/debounced function, and I'm certain that with ES6 arrow functions we will see such things fewer. But you're right, it's an underscorejs convention that all callback-taking functions also take a this context.Costive
A
1

As my TL pointed out today, It is worth mentioning that in the popular implementation of this 2 functions in lodash:

The throttle function is actually just a specific configuration of debounce:

function throttle(func, wait, options) {
  let leading = true
  let trailing = true

  if (typeof func != 'function') {
    throw new TypeError('Expected a function')
  }
  if (isObject(options)) {
    leading = 'leading' in options ? !!options.leading : leading
    trailing = 'trailing' in options ? !!options.trailing : trailing
  }
  return debounce(func, wait, {
    'leading': leading,
    'maxWait': wait,
    'trailing': trailing
  })
}
Alfredoalfresco answered 31/8, 2018 at 14:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.