debounce.js 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. var restArguments = require('./restArguments.js');
  2. var now = require('./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. 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. }
  36. module.exports = debounce;