79376012

Date: 2025-01-21 21:48:11
Score: 0.5
Natty:
Report link

We literally had this exact same requirement.

  1. Debounced function runs immediately on first call.
  2. After the first call, subsequent requests are debounced until some delay has passed ("the batching period")
  3. Once the batching period is over, repeat step 1.

Check out this blog post.

Here's the code:

class SmartDebounce {
  private isBatching: boolean = false;
  private debounceTimer: NodeJS.Timeout | null = null;
  private readonly debounceInterval: number;

  public hasQueuedUpdate: boolean = false;

  constructor(debounceIntervalMs: number = 25) {
    this.debounceInterval = debounceIntervalMs;

    this.cleanup = this.cleanup.bind(this);
    this.run = this.run.bind(this);
    this.debounce = this.debounce.bind(this);
    this.cleanup = this.cleanup.bind(this);
  }

  public run(callback: () => Promise < void > | void): void {
    if (!this.isBatching) {
      this.isBatching = true;

      this.debounce(() => {
        this.isBatching = false;
      });

      // Run the callback immediately
      this.hasQueuedUpdate = false;
      callback();
    } else {
      this.hasQueuedUpdate = true;

      this.debounce(() => {
        this.isBatching = false;
        this.hasQueuedUpdate = false;

        callback();
      });
    }
  }

  private debounce(callback: () => Promise < void > | void): void {
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer);
    }

    this.debounceTimer = setTimeout(() => {
      callback();
    }, this.debounceInterval);
  }

  public cleanup(): void {
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer);
    }
  }
}

Reasons:
  • Blacklisted phrase (1): this blog
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: user29304288