throttle.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. var debounce = require('./debounce'),
  2. isObject = require('../lang/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 invocations. Provide an options object to indicate
  9. * that `func` should be invoked on the leading and/or trailing edge of the
  10. * `wait` timeout. Subsequent calls to the throttled function return the
  11. * result of the last `func` call.
  12. *
  13. * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
  14. * on the trailing edge of the timeout only if the the throttled function is
  15. * invoked more than once during the `wait` timeout.
  16. *
  17. * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
  18. * for details over the differences between `_.throttle` and `_.debounce`.
  19. *
  20. * @static
  21. * @memberOf _
  22. * @category Function
  23. * @param {Function} func The function to throttle.
  24. * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
  25. * @param {Object} [options] The options object.
  26. * @param {boolean} [options.leading=true] Specify invoking on the leading
  27. * edge of the timeout.
  28. * @param {boolean} [options.trailing=true] Specify invoking on the trailing
  29. * edge of the timeout.
  30. * @returns {Function} Returns the new throttled function.
  31. * @example
  32. *
  33. * // avoid excessively updating the position while scrolling
  34. * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
  35. *
  36. * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
  37. * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
  38. * 'trailing': false
  39. * }));
  40. *
  41. * // cancel a trailing throttled call
  42. * jQuery(window).on('popstate', throttled.cancel);
  43. */
  44. function throttle(func, wait, options) {
  45. var leading = true,
  46. trailing = true;
  47. if (typeof func != 'function') {
  48. throw new TypeError(FUNC_ERROR_TEXT);
  49. }
  50. if (options === false) {
  51. leading = false;
  52. } else 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, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
  57. }
  58. module.exports = throttle;