throttle.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. var debounce = require('./debounce'),
  2. isObject = require('./isObject');
  3. /** Used as the `TypeError` message for "Functions" methods. */
  4. var FUNC_ERROR_TEXT = 'Expected a function';
  5. /**
  6. * Creates a throttled function that only invokes `func` at most once per
  7. * every `wait` milliseconds. The throttled function comes with a `cancel`
  8. * method to cancel delayed `func` invocations and a `flush` method to
  9. * immediately invoke them. Provide an options object to indicate whether
  10. * `func` should be invoked on the leading and/or trailing edge of the `wait`
  11. * timeout. The `func` is invoked with the last arguments provided to the
  12. * throttled function. Subsequent calls to the throttled function return the
  13. * result of the last `func` invocation.
  14. *
  15. * **Note:** If `leading` and `trailing` options are `true`, `func` is
  16. * invoked on the trailing edge of the timeout only if the throttled function
  17. * is invoked more than once during the `wait` timeout.
  18. *
  19. * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
  20. * for details over the differences between `_.throttle` and `_.debounce`.
  21. *
  22. * @static
  23. * @memberOf _
  24. * @since 0.1.0
  25. * @category Function
  26. * @param {Function} func The function to throttle.
  27. * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
  28. * @param {Object} [options={}] The options object.
  29. * @param {boolean} [options.leading=true]
  30. * Specify invoking on the leading edge of the timeout.
  31. * @param {boolean} [options.trailing=true]
  32. * Specify invoking on the trailing edge of the timeout.
  33. * @returns {Function} Returns the new throttled function.
  34. * @example
  35. *
  36. * // Avoid excessively updating the position while scrolling.
  37. * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
  38. *
  39. * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
  40. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
  41. * jQuery(element).on('click', throttled);
  42. *
  43. * // Cancel the trailing throttled invocation.
  44. * jQuery(window).on('popstate', throttled.cancel);
  45. */
  46. function throttle(func, wait, options) {
  47. var leading = true,
  48. trailing = true;
  49. if (typeof func != 'function') {
  50. throw new TypeError(FUNC_ERROR_TEXT);
  51. }
  52. if (isObject(options)) {
  53. leading = 'leading' in options ? !!options.leading : leading;
  54. trailing = 'trailing' in options ? !!options.trailing : trailing;
  55. }
  56. return debounce(func, wait, {
  57. 'leading': leading,
  58. 'maxWait': wait,
  59. 'trailing': trailing
  60. });
  61. }
  62. module.exports = throttle;