You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
2.6 KiB

4 years ago
  1. var debounce = require('./debounce'),
  2. isObject = require('./isObject');
  3. /** Error message constants. */
  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 `options` to indicate whether `func`
  10. * 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. * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
  20. * until to the next tick, similar to `setTimeout` with a timeout of `0`.
  21. *
  22. * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
  23. * for details over the differences between `_.throttle` and `_.debounce`.
  24. *
  25. * @static
  26. * @memberOf _
  27. * @since 0.1.0
  28. * @category Function
  29. * @param {Function} func The function to throttle.
  30. * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
  31. * @param {Object} [options={}] The options object.
  32. * @param {boolean} [options.leading=true]
  33. * Specify invoking on the leading edge of the timeout.
  34. * @param {boolean} [options.trailing=true]
  35. * Specify invoking on the trailing edge of the timeout.
  36. * @returns {Function} Returns the new throttled function.
  37. * @example
  38. *
  39. * // Avoid excessively updating the position while scrolling.
  40. * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
  41. *
  42. * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
  43. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
  44. * jQuery(element).on('click', throttled);
  45. *
  46. * // Cancel the trailing throttled invocation.
  47. * jQuery(window).on('popstate', throttled.cancel);
  48. */
  49. function throttle(func, wait, options) {
  50. var leading = true,
  51. trailing = true;
  52. if (typeof func != 'function') {
  53. throw new TypeError(FUNC_ERROR_TEXT);
  54. }
  55. if (isObject(options)) {
  56. leading = 'leading' in options ? !!options.leading : leading;
  57. trailing = 'trailing' in options ? !!options.trailing : trailing;
  58. }
  59. return debounce(func, wait, {
  60. 'leading': leading,
  61. 'maxWait': wait,
  62. 'trailing': trailing
  63. });
  64. }
  65. module.exports = throttle;