You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多倒计时器场景下如何终止对应正确的Web Worker实例?

问题分析

你的核心问题在于全局变量w被重复覆盖了!每次调用startTimer时,你都把新创建的Worker赋值给全局的w,导致所有计时器的onmessage回调里,w最终指向的都是最后一个创建的Worker实例。所以不管哪个计时器到期,终止的都是最后那个Worker。

修复方案

把Worker的引用改成局部变量,确保每个startTimer调用都持有自己独立的Worker实例。同时可以用一个对象来映射每个timerId对应的Worker,方便后续管理(比如手动终止)。

以下是修改后的完整代码:

$(document).ready(function() {
  // 用一个对象存储timerId和对应的Worker实例,方便管理
  const workerMap = {};

  $('.frequency-item').each(function(i, e) {
    const children = $(e).children();
    const observationLengthInMinutesId = children[1].id;
    const timerId = children[3].id;
    startTimer(observationLengthInMinutesId, timerId, workerMap);
  });
});

function startTimer(observationLengthInMinutesId, timerId, workerMap) {
  // 用let声明局部变量w,避免全局覆盖
  let w = null;
  if (typeof(Worker) !== "undefined") {
    if (w == null) {
      w = new Worker("/js/simple-timer.js");
      // 把Worker实例存入映射表
      workerMap[timerId] = w;
      w.postMessage($('#' + observationLengthInMinutesId).val());
    }

    w.onmessage = function(event) {
      $('#' + timerId).text(event.data);

      if (event.data === '00:00') {
        // 终止当前对应的Worker实例
        w.terminate();
        // 从映射表中移除,避免内存泄漏
        delete workerMap[timerId];
      }
    };

    // 可选:监听Worker错误,及时清理资源
    w.onerror = function(error) {
      console.error(`Worker error for timer ${timerId}:`, error);
      w.terminate();
      delete workerMap[timerId];
    };
  } else {
    $('#' + timerId).text("Sorry, your browser does not support Web Workers ...");
  }
}
关键修改点
  1. 局部变量替代全局变量:用let w在startTimer内部声明Worker变量,每个计时器调用都会创建独立的引用,不会被后续调用覆盖。
  2. Worker映射表:新增workerMap对象存储每个timerId对应的Worker实例,不仅能确保终止正确的Worker,还方便后续如果需要手动终止某个计时器(比如用户点击取消按钮)时快速找到对应的Worker。
  3. 清理映射表:终止Worker后从workerMap中删除对应条目,避免内存泄漏。

这样修改后,每个计时器到期时,都会精准终止自己对应的Web Worker实例啦!

内容的提问来源于stack exchange,提问作者Gianluca78

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:17:37