Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debounce ignore next #437

Open
ramiel opened this issue Nov 18, 2024 · 0 comments
Open

Debounce ignore next #437

ramiel opened this issue Nov 18, 2024 · 0 comments

Comments

@ramiel
Copy link

ramiel commented Nov 18, 2024

Following the issue #362 and before creating any PR, I want to describe my use case. I have a slider (like a video player slider). This slider has two events:

  • onChange
  • onChangeEnd

onChangeEnd is raised when the user mouse is up, otherwise any movement of the slider raises a onChange. When the user move the slider I want to show something, e.g. the time, but I want this function to be debounced. When the user end the changes I want to clean the output.
Now, if the user simply clicks on the slider, I don't want to show anything.

With the current debounce implementation this is not possible because eventually the time is shown. I'd like to cancel the execution of the next debounced function but only until I need it again.

In the mentioned issue they're arguing about a pause function. I need something similar that I call ignore. Ignore, simply ignores the next execution. I have my alternative implementation of debounce, taken from the current one

/* eslint-disable @typescript-eslint/no-explicit-any */
export type DebounceFunction<TArgs extends any[]> = {
  (...args: TArgs): void;
  /**
   * Cancels the debounced function
   */
  cancel(): void;
  /**
   * Ignores the current debounced function if any
   */
  ignore(): void;
  /**
   * Checks if there is any invocation debounced
   */
  isPending(): boolean;
  /**
   * Runs the debounced function immediately
   */
  flush(...args: TArgs): void;
};

/**
 * A slightly modifed version of radash debounce implementation
 *
 */
export const debounce = <TArgs extends any[]>(
  { delay }: { delay: number },
  func: (...args: TArgs) => any
) => {
  let timer: NodeJS.Timeout | undefined = undefined;
  let active = true;

  const debounced: DebounceFunction<TArgs> = (...args: TArgs) => {
    if (active) {
      clearTimeout(timer);
      timer = setTimeout(() => {
        active && func(...args);
        timer = undefined;
      }, delay);
    } else {
      func(...args);
    }
  };
  debounced.isPending = () => {
    return timer !== undefined;
  };
  debounced.cancel = () => {
    active = false;
  };
  debounced.flush = (...args: TArgs) => func(...args);

  debounced.ignore = () => {
    clearTimeout(timer);
  };

  return debounced;
};

As you can see the effect is got by simply ignoring the current timeout. I don't know if this covers also the problem in the other issue and I don't know if you want me to propose a PR with this change.

If this is not in the scope of how the debounce function should work, please ignore and close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant