【问题标题】:How to restart web workers when computer restarts from sleep mode?计算机从睡眠模式重新启动时如何重新启动网络工作者?
【发布时间】:2020-03-19 09:05:43
【问题描述】:

我有一个简单的网络工作者,它使用 setInterval 保持时区的当前时间

setInterval(() => {
        userTimezoneTimestamp = userTimezoneTimestamp + 1000
        postMessage(userTimezoneTimestamp);
    }, 1000);

在我将机器置于睡眠模式之前它工作正常。当我从睡眠模式重新启动机器时,我从这个工人那里得到的时间更久。 如何仅在机器从睡眠模式启动时重新启动我的网络工作者?

【问题讨论】:

  • 每隔 X 秒也为userTimezoneTimestampvariable 设置间隔。当机器从睡眠模式启动时,此同步 userTimezoneTimestamp
  • 我怀疑你问的是可能的。浏览器有权随时暂停任何打开的选项卡及其工作人员。\
  • 我不明白你在做什么,为什么以及你所要求的会有所帮助。您的工作人员应至少与您的主页同时重新启动。不是这样吗?你到底在做什么,你有什么确切的行为,应该是什么?这是一个小操场,您可以对其进行编辑以使您的案例更清晰。 jsfiddle.net/m9tjo6h5
  • 嗨@Kaiido,我正在使用 webworker 维护用户的时区的当前时间戳,就像你在 Jsfiddle 中所做的那样。但是,一旦您将 PC 置于睡眠模式,网络工作者就会停止工作。当我启动 PC 时,我从 webworker 获得的时间戳是旧的。现在我想要一个窗口事件,它可以让我知道应用程序从睡眠模式恢复。正如恢复莫妮卡所说,我认为这是不可能的
  • 为什么要举办这样的活动?你认为这会有什么帮助? “老了”是什么意思?你如何获得初始时间戳?

标签: javascript events web-worker sleep-mode


【解决方案1】:

似乎没有任何 DOM 事件让我们知道该事件。

在我的笔记本上,Chrome 确实会触发一个非标准的 orientationabsolutechange 事件,但我认为并非所有笔记本都有方向感知硬件,而且同一台机器上的 Firefox 已经不会触发它。

但是对于你想要的(从 API 提供的时间戳始终保持最新的偏移量),你根本不需要 WebWorker,也不需要任何计时器,计算机配备了一个很好的,不仅它仍然是电脑休眠后​​更新,甚至比你的时间间隔更精确。

您只需要存储从 API 获得的偏移量以及您收到它的计算机时间。然后你只需要得到现在和接收时间之间的差异,你就可以很容易地得到你更新的偏移量。

OP 指出,他们担心用户将计算机的时间修改为更早的日期,从而在页面运行时弄乱Date 的值。 可以检测到。只需存储最后一个值,并检查与当前值的差异是否为负。

( async () => {

  const offset_from_API = await getOffsetFromAPI();
  const time_received = Date.now();
  let last_time = time_received;
  
  
  const getUpToDateOffset = () => {
    const now = Date.now();
    // Anti-Back-Time-Travelling check
    // (it's a good idea to poll this method quite often too update `last_time`)
    if( now - last_time < 0 ) {
      throw new Error( 'cheater detected' );
    }
    last_time = now;
    
    return offset_from_API + (now - time_received);

  };
  
  // to compare we will also use an incrementer
  let incremented = offset_from_API;
  setInterval( () => {
    incremented += 1000;
    console.clear();
    console.log( 'incremented', incremented.toLocaleString( 'en-US' ) );
    console.log( 'difference ', getUpToDateOffset().toLocaleString( 'en-US' ) );
  }, 1000 );
  
} )();

function getOffsetFromAPI() { return 1234567; }

【讨论】:

  • 感谢@Kaiido,在我们的应用程序中,我们无法回复客户时间。 Date.now() 函数返回计算机的时间,我们可以很容易地将其设置为过去的时间。如果用户将计算机时间更改为过去时间,使用 Date.now() 函数我们将无法获得正确的时间。这就是为什么我们从服务器获取当前时间并在客户端使用 web worker 中的 setInterval 维护它的原因。在这种睡眠模式场景之前一切正常
  • @HarshalRinge 编辑了我的答案。可以检测到该事件(当用户将其时钟设置为前一个日期时)。另一方面,计算机无法唤醒。
  • 非常感谢@Kaiido,performance.now() 对我来说很有用。我已经更改了我的代码,我会更新作为答案。非常感谢!
  • performance.now 将在浏览器休眠时“暂停”,最后不是一个好的 odea,抱歉。用户的 Checkong 以最可靠的方式更改了他们的时钟设置
  • 嗨@Kaiido,你说的浏览器休眠是什么意思?我通过将机器时间更改为过去时间来测试它,我还通过将机器置于睡眠模式来检查它。在这两种情况下,它都运行良好。当系统从睡眠模式唤醒时,它会在 performance.now() 中给出正确的值。谢谢:)
【解决方案2】:
setInterval(() => {
        /*handle userTimezoneTimestamp stuff every N miliseconds */
    }, N);


setInterval(() => {
        userTimezoneTimestamp = userTimezoneTimestamp + 1000
        postMessage(userTimezoneTimestamp);
    }, 1000);

【讨论】:

    猜你喜欢
    • 2019-11-07
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2019-03-09
    • 2013-10-10
    • 1970-01-01
    • 2019-11-23
    • 2018-09-20
    相关资源
    最近更新 更多