Worker 心跳轮询核心是将定时请求移出主线程,通过 postMessage 通信实现无感 UI 更新;需处理异常、退避重试与生命周期清理,并优先选用 SSE 或 WebSocket。

用 Worker 线程做心跳轮询,核心是把定时请求逻辑从主线程剥离,避免阻塞渲染和交互。关键不在于“轮询多频繁”,而在于“请求是否真在后台跑、失败是否可感知、UI 是否完全无感”。
Worker 中封装独立的轮询逻辑
不能直接在 Worker 里用 fetch 后立刻更新 DOM(Worker 没有 DOM API),而是通过 postMessage 把结果传回主线程处理:
- 在 Worker 文件(如
heartbeat.js)中用setInterval发起fetch,带上必要的鉴权头或参数 - 每次请求后检查响应状态(如
response.ok或自定义 code 字段),成功/失败都postMessage通知主线程 - 捕获网络异常(
try/catch)、超时(用AbortSignal.timeout())、重定向限制,避免静默失败 - 建议加简单退避:连续失败 3 次后暂停 30 秒再试,防止雪崩请求
主线程只负责接收和轻量响应
主线程收到消息后,仅做 UI 状态同步(比如更新连接图标、显示“离线”提示),不做耗时操作:
- 监听
worker.onmessage,根据data.status更新一个响应式变量(如 Vue 的 ref / React 的 useState) - 避免在 onmessage 回调里发起新请求、解析大 JSON 或触发复杂计算
- 若需重试控制(如用户点击“重连”),由主线程发
worker.postMessage({ action: 'retry' }),Worker 再执行
注意生命周期与资源清理
Worker 不是永远运行的,页面关闭、Tab 切走、系统休眠都可能终止它:
- 在主线程监听页面卸载事件(
beforeunload或pagehide),主动worker.terminate() - Worker 内监听
self.onmessage接收终止信号,清理clearInterval - 不要依赖 Worker 的全局变量存状态;心跳结果应以消息形式实时上报,主线程自己维护最新状态
替代方案:优先考虑 Server-Sent Events 或 WebSocket
纯轮询本质是模拟长连接,有延迟和资源浪费。如果服务端支持:
- SSE 更轻量:Worker 中用
EventSource监听,天然支持自动重连,消息即来即发 - WebSocket 更实时:Worker 虽不能直接创建 WS(多数浏览器限制),但可在主线程建连,将心跳保活逻辑交给服务端,Worker 只负责监听
message和异常并上报 - 只有服务端不支持推送时,才用 Worker + fetch 轮询,且务必设好合理间隔(如 30s~2min)

















