{
  "id": 2117530,
  "title": "The Background-Tab Bug I Missed in My JavaScript Polling Code",
  "url": "https://urgent.news/2026/08/20/the-background-tab-bug-i-missed-in-my-javascript-polling-code",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-20T10:50:13.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/phpner/the-background-tab-bug-i-missed-in-my-javascript-polling-code-3ol3"
  },
  "original_language": "en",
  "account": "The issue with JavaScript polling code is that replacing setInterval() with recursive setTimeout() did not fully ensure safe execution. Although only one request would run at a time, and the next timeout was cleared when the page became hidden, there was still a race condition. If the page became visible again before the old request finished, a new polling run could start, potentially overwriting fresher state with an old response. Clearing the timeout with clearTimeout() did not protect the UI from this problem. The race condition was more dangerous than the previously investigated timer drift. To fix this issue, three separate decisions were required: timestamps to measure elapsed time, visibility changes triggering resynchronization, and cancellation along with a run identifier to prevent stale requests from updating state.",
  "summary": "I thought replacing setInterval() with recursive setTimeout() had made a polling loop safe. Only one request would run at a time, and I cleared the next timeout when the page became hidden. It still had a race. The timeout was gone. The request already in flight was not. If the page became visible again before that old request finished, a new polling run could start. The old response could then…",
  "key_points": [
    "Clearing timeout with clearTimeout() does not protect UI from race condition issue",
    "Fix requires timestamps, visibility changes, and cancellation with run identifier"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}