🟑 MediumAsync BugsπŸ› Debug Challenge

setInterval accumulates β€” not cleared on re-render

Buggy Code β€” Can you spot the issue?

class DataPoller {
  constructor(url) {
    this.url = url;
    this.data = null;
  }

  startPolling(interval = 1000) {
    setInterval(async () => {
      const res = await fetch(this.url);
      this.data = await res.json();
      console.log('Updated:', this.data);
    }, interval);
  }

  stopPolling() {
    // ??? β€” no way to stop it
  }
}

const poller = new DataPoller('/api/status');
poller.startPolling(); // interval #1
poller.startPolling(); // interval #2 β€” #1 still running!

Fixed Code

class DataPoller {
  constructor(url) {
    this.url = url;
    this.data = null;
    this._intervalId = null;
  }

  startPolling(interval = 1000) {
    this.stopPolling(); // clear any existing interval first
    this._intervalId = setInterval(async () => {
      const res = await fetch(this.url);
      this.data = await res.json();
      console.log('Updated:', this.data);
    }, interval);
  }

  stopPolling() {
    if (this._intervalId !== null) {
      clearInterval(this._intervalId);
      this._intervalId = null;
    }
  }
}

Bug Explained

Bug: setInterval returns an ID needed for clearInterval. Without storing it, you can never cancel the interval. Each startPolling() call piles up another interval.

Explanation: Store the interval ID and clear it before creating a new one. stopPolling() uses the stored ID to call clearInterval. Guards with !== null for safety.

Key Insight: Every setInterval must have a corresponding clearInterval. Always store the ID. Clear before re-creating to avoid accumulating intervals.

More Async Bugs Debug Challenges

🟒 EasyMissing await causes wrong resultβ†’πŸŸ‘ MediumSequential awaits killing performanceβ†’πŸŸ‘ MediumSwallowed error in async functionβ†’πŸ”΄ HardAsync function in forEachβ†’

Practice spotting bugs live β†’

38 debug challenges with AI hints

πŸ› Try Debug Lab