index.cjs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. 'use strict';
  2. const DEBOUNCE_DEFAULTS = {
  3. trailing: true
  4. };
  5. function debounce(fn, wait = 25, options = {}) {
  6. options = { ...DEBOUNCE_DEFAULTS, ...options };
  7. if (!Number.isFinite(wait)) {
  8. throw new TypeError("Expected `wait` to be a finite number");
  9. }
  10. let leadingValue;
  11. let timeout;
  12. let resolveList = [];
  13. let currentPromise;
  14. let trailingArgs;
  15. const applyFn = (_this, args) => {
  16. currentPromise = _applyPromised(fn, _this, args);
  17. currentPromise.finally(() => {
  18. currentPromise = null;
  19. if (options.trailing && trailingArgs && !timeout) {
  20. const promise = applyFn(_this, trailingArgs);
  21. trailingArgs = null;
  22. return promise;
  23. }
  24. });
  25. return currentPromise;
  26. };
  27. return function(...args) {
  28. if (currentPromise) {
  29. if (options.trailing) {
  30. trailingArgs = args;
  31. }
  32. return currentPromise;
  33. }
  34. return new Promise((resolve) => {
  35. const shouldCallNow = !timeout && options.leading;
  36. clearTimeout(timeout);
  37. timeout = setTimeout(() => {
  38. timeout = null;
  39. const promise = options.leading ? leadingValue : applyFn(this, args);
  40. for (const _resolve of resolveList) {
  41. _resolve(promise);
  42. }
  43. resolveList = [];
  44. }, wait);
  45. if (shouldCallNow) {
  46. leadingValue = applyFn(this, args);
  47. resolve(leadingValue);
  48. } else {
  49. resolveList.push(resolve);
  50. }
  51. });
  52. };
  53. }
  54. async function _applyPromised(fn, _this, args) {
  55. return await fn.apply(_this, args);
  56. }
  57. exports.debounce = debounce;