HTML5 Web Workers怎么识别_HTML5后台线程特征识别【线程】

Web Workers 存活判断需监听 onmessage/onerror 并发送心跳,不可依赖 worker 对象存在或不存在的 state 属性;Dedicated 与 Shared Worker 须严格区分创建方式、作用域及通信机制;崩溃识别依赖错误事件与 postMessage 异常;任务执行状态通过 busy/idle 消息标记检测。

Web Workers 实例是否存活的判断方法

不能靠 worker 对象是否存在来判断线程是否还在运行——它可能已终止但引用未被回收。真正可靠的识别方式是监听 worker.onmessageworker.onerror,并配合主动发送心跳消息。

  • worker.postMessage() 发送后若触发 onerror(错误信息含 "Failed to execute 'postMessage' on 'Worker'"),说明线程已销毁
  • 在 Worker 内定期调用 self.postMessage({ type: 'heartbeat' }),主线程收到即确认存活;超时未收则视为失联
  • 注意:worker.state 属性不存在,HTML5 规范未定义该字段,任何依赖它的检测都不可靠

如何区分 Dedicated Worker 和 Shared Worker

两者启动方式、作用域和通信模型完全不同,混淆会导致 ReferenceError 或静默失败。

  • Dedicated Worker 由 new Worker('script.js') 创建,仅与创建它的脚本通信;self instanceof DedicatedWorkerGlobalScope 在内部为 true
  • Shared Worker 必须用 new SharedWorker('script.js'),通过 port.postMessage() 通信;其全局作用域是 SharedWorkerGlobalScope
  • 在 Worker 脚本中可通过 self.constructor.name 判断:
    console.log(self.constructor.name); // "DedicatedWorkerGlobalScope" 或 "SharedWorkerGlobalScope"

Worker 线程崩溃或异常退出的痕迹识别

Worker 崩溃不会抛出主线程错误,但会留下可捕获的信号。关键不是“有没有报错”,而是“有没有断连”。

  • 主线程监听 worker.onerror:错误对象 event.filename 指向 Worker 脚本路径,event.lineno/event.colno 可定位源码位置
  • Worker 内部必须显式捕获未处理异常:
    self.addEventListener('error', e => {
      self.postMessage({ type: 'crash', message: e.message, filename: e.filename });
    });
  • 若主线程长时间未收到任何 message,且后续 postMessageInvalidStateError: Failed to execute 'postMessage' on 'Worker': Worker is either in the process of being shut down or has been shut down,即可判定已退出

Worker 是否正在执行计算任务的轻量检测

没有直接 API 获取 Worker 当前 CPU 占用或调用栈,但可通过协作式标记 + 时间戳实现近似判断。

  • 在 Worker 中每次进入耗时逻辑前发一次 self.postMessage({ type: 'busy', ts: Date.now() }),完成后发 { type: 'idle' }
  • 主线程维护一个 lastBusyTime,若距今超过阈值(如 500ms)且未收到 idle,可认为仍在执行中
  • 避免轮询:改用 MessageChannel 实现双向响应式通信,减少无意义消息;port.start() 后才能接收 message 事件
实际部署中,最容易被忽略的是 Shared Worker 的同源限制和端口激活机制——跨 tab 共享时,必须调用 port.start() 才能收发消息,否则所有 postMessage 都静默丢弃。