debounce.js 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. define(['./restArguments', './now'], function (restArguments, now) {
  2. // When a sequence of calls of the returned function ends, the argument
  3. // function is triggered. The end of a sequence is defined by the `wait`
  4. // parameter. If `immediate` is passed, the argument function will be
  5. // triggered at the beginning of the sequence instead of at the end.
  6. function debounce(func, wait, immediate) {
  7. var timeout, previous, args, result, context;
  8. var later = function() {
  9. var passed = now() - previous;
  10. if (wait > passed) {
  11. timeout = setTimeout(later, wait - passed);
  12. } else {
  13. timeout = null;
  14. if (!immediate) result = func.apply(context, args);
  15. // This check is needed because `func` can recursively invoke `debounced`.
  16. if (!timeout) args = context = null;
  17. }
  18. };
  19. var debounced = restArguments(function(_args) {
  20. context = this;
  21. args = _args;
  22. previous = now();
  23. if (!timeout) {
  24. timeout = setTimeout(later, wait);
  25. if (immediate) result = func.apply(context, args);
  26. }
  27. return result;
  28. });
  29. debounced.cancel = function() {
  30. clearTimeout(timeout);
  31. timeout = args = context = null;
  32. };
  33. return debounced;
  34. }
  35. return debounce;
  36. });