my-swiss-knife: - v1.9.9
    Preparing search index...

    Function withDebounce

    • Creates a debounced version of the provided callback function. The debounced function delays the invocation of the callback until after a specified wait time has elapsed since the last time it was called.

      Supports options for:

      • leading: invoke the function on the leading edge of the delay
      • trailing: invoke the function on the trailing edge (default behavior)
      • maxWait: ensure the function is called at least once within the max wait time

      Parameters

      • callback: (...args: unknown[]) => void

        The function to debounce.

      • Optionaldelay: number = 100

        The number of milliseconds to delay.

      • Optionaloptions: { leading?: boolean; maxWait?: number; trailing?: boolean } = {}

        Optional settings.

        • Optionalleading?: boolean

          Whether to invoke on the leading edge.

        • OptionalmaxWait?: number

          Maximum time to wait before forcing a call.

        • Optionaltrailing?: boolean

          Whether to invoke on the trailing edge.

      Returns DebouncedFunction

      A debounced function with a .cancel() method to clear pending calls.

      const log = withDebounce(console.log, 300, { leading: true, trailing: true });
      log('hello'); // logs immediately
      log('world'); // ignored
      setTimeout(() => log('again'), 400); // logs 'again' after delay
      const fn = withDebounce(fetchData, 200, { maxWait: 1000 });
      window.addEventListener('resize', fn);

      // To cancel:
      fn.cancel();
      export const withDebounce = (
      callback: (...args: unknown[]) => void,
      delay: number = 100,
      options: {
      leading?: boolean;
      trailing?: boolean;
      maxWait?: number;
      } = {}
      ): DebouncedFunction => {
      let timeout: ReturnType<typeof setTimeout> | null = null;
      let maxWaitTimeout: ReturnType<typeof setTimeout> | null = null;
      let lastArgs: unknown[] | null = null;
      let lastThis: any = null;
      let calledLeading = false;

      const { leading = false, trailing = true, maxWait } = options;

      const clearTimers = () => {
      if (timeout) clearTimeout(timeout);
      if (maxWaitTimeout) clearTimeout(maxWaitTimeout);
      timeout = null;
      maxWaitTimeout = null;
      };

      const invokeCallback = () => {
      if (trailing && lastArgs) {
      callback.apply(lastThis, lastArgs);
      }
      clearTimers();
      lastArgs = null;
      lastThis = null;
      calledLeading = false;
      };

      const debounced = function (this: any, ...args: unknown[]) {
      lastArgs = args;
      lastThis = this;

      const shouldCallLeading = leading && !calledLeading;

      if (shouldCallLeading) {
      callback.apply(lastThis, lastArgs);
      calledLeading = true;
      lastArgs = null;
      lastThis = null;
      }

      if (timeout) clearTimeout(timeout);
      timeout = setTimeout(invokeCallback, delay);

      if (maxWait && !maxWaitTimeout) {
      maxWaitTimeout = setTimeout(() => {
      if (lastArgs) {
      callback.apply(lastThis, lastArgs);
      clearTimers();
      lastArgs = null;
      lastThis = null;
      calledLeading = false;
      }
      }, maxWait);
      }
      } as DebouncedFunction;

      debounced.cancel = () => {
      clearTimers();
      lastArgs = null;
      lastThis = null;
      calledLeading = false;
      };

      return debounced;
      };