debounce.js 1.2 KB

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