index.js 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. 'use strict';
  2. const mimicFn = require('mimic-fn');
  3. module.exports = (inputFunction, options = {}) => {
  4. if (typeof inputFunction !== 'function') {
  5. throw new TypeError(`Expected the first argument to be a function, got \`${typeof inputFunction}\``);
  6. }
  7. const {
  8. wait = 0,
  9. before = false,
  10. after = true
  11. } = options;
  12. if (!before && !after) {
  13. throw new Error('Both `before` and `after` are false, function wouldn\'t be called.');
  14. }
  15. let timeout;
  16. let result;
  17. const debouncedFunction = function (...arguments_) {
  18. const context = this;
  19. const later = () => {
  20. timeout = undefined;
  21. if (after) {
  22. result = inputFunction.apply(context, arguments_);
  23. }
  24. };
  25. const shouldCallNow = before && !timeout;
  26. clearTimeout(timeout);
  27. timeout = setTimeout(later, wait);
  28. if (shouldCallNow) {
  29. result = inputFunction.apply(context, arguments_);
  30. }
  31. return result;
  32. };
  33. mimicFn(debouncedFunction, inputFunction);
  34. debouncedFunction.cancel = () => {
  35. if (timeout) {
  36. clearTimeout(timeout);
  37. timeout = undefined;
  38. }
  39. };
  40. return debouncedFunction;
  41. };