计算机进入睡眠状态时setTimeout会发生什么?

时间:2011-06-14 16:30:04

标签: javascript settimeout

在现代网络浏览器中,假设我执行setTimeout 10分钟(在12:00),5分钟后让计算机进入睡眠状态,系统再次唤醒时会发生什么?如果在10分钟之前(12:09)或之后(16:00)醒来会发生什么?

我问的原因是因为我想每10分钟要求一个新的身份验证令牌,我不确定浏览器是否会做正确的事情,如果它醒来就立即请求新的令牌经过很长一段时间。

澄清:我不想使用cookies - 我正在尝试在这里建立一个Web服务;是的,服务器将拒绝旧的和无效的令牌。

7 个答案:

答案 0 :(得分:42)

据我测试过,它只是在计算机唤醒后停止并恢复。我认为这意味着会话取决于setTimeout/Interval,计算机从计算机入睡时开始计时。

我认为你不应该依赖setTimeout/Interval对时间关键的准确性。对于谷歌浏览器我discovered recently,任何超时/间隔(短于1秒)将被减慢到每秒一次,如果激活它的选项卡失去焦点。

除此之外,超时/间隔的准确性取决于其他运行的功能等。简而言之:它不是很准确。

因此,使用间隔和超时,检查由它启动的函数内的开始时间的时间将为您提供更好的准确性。现在,如果你从12:00开始,计算机将进入睡眠状态并在16:13左右醒来,检查16:13对抗12:00您确定必须更新令牌。可以找到使用时间比较的示例here

答案 1 :(得分:6)

将当前日期时间与加载页面时的日期时间进行比较,如下所示:

//Force refresh after x minutes.
var initialTime = new Date();
var checkSessionTimeout = function () {
    var minutes = Math.abs((initialTime - new Date()) / 1000 / 60);
    if (minutes > 20) {
        setInterval(function () { location.href = 'Audit.aspx' }, 5000)
    } 
};
setInterval(checkSessionTimeout, 1000);

答案 2 :(得分:4)

该行为基于浏览器和操作系统。操作系统处理睡眠,个别应用程序通常不会考虑它。

最有可能发生的事情是,操作系统将在计时器停留的同一时间恢复到关机状态。另一种可能性是它根本不会发射。

如果真的是一个问题,你可能希望比抱歉更安全,并存储令牌初始化的时间戳,并使用setInterval定期检查(比如每分钟两次)。< / p>

但是,安全性不应仅仅是客户端的事情。如果使用旧的/无效的令牌并且Ajax在响应中表现得恰当,请确保您的服务器抛出错误。

[编辑] 我同意另一篇文章,它可能会在下一个时间点立即触发。 Resig的博文非常好。

答案 3 :(得分:3)

这是我的代码:

<!doctype html>
<html>

<body>
<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 120000)"/>

</body>
<script>


</script>
</html>

我已经采取了三种可能回答这个问题的方案。

场景1:在00秒时点击“开始计时器”按钮。 25秒钟,电脑就睡着了。 在1分40秒唤醒电脑。 在2分钟时显示警报。

场景2:在00秒时点击“开始计时器”按钮。 26秒钟,电脑就睡着了。 3分钟后,我唤醒了电脑。显示警报。

情景3:这个真的令人震惊。

<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 600000)"/>

在00秒时,我点击“开始计时器”按钮。 在1分30秒左右,计算机处于休眠模式(我的电脑需要一分钟才能启动休眠)

8分钟后我打开笔记本电脑。 在10分钟时,警报会弹出。

PS: This is my first ever comment on Stack Exchange. I prefer to execute code and view results rather than infer from theory.

答案 4 :(得分:2)

JavaScript计时器(setTimeout)在多种情况下的行为。

  1. 当线程空闲且超时触发时:超时后立即触发定时器。它可能具有约0-5毫秒的某些不精确度(典型情况)。
  2. 当线程超忙(巨大的循环)足够长时间以传递定时器超时时:定时器将在释放线程后立即执行。
  3. 当有警报时:与2相同的行为。
  4. 当线程暂停因为我们的笔记本电脑进入睡眠状态时:我已经看到了几件事。但最常见的是完全不准确,忽略了睡觉时间。
  5. 由于JavaScript中的计时器基于CPU计时器,并且CPU处于休眠状态,因此计时器完全暂停并恢复为“因为什么都不会发生”。

答案 5 :(得分:1)

根据Ben的回答,我创建了以下util。您可以调整采样持续时间,但我使用它就像令牌刷新一样:

const absoluteSetInterval = (handler, timeout) => {
  let baseTime = Date.now();
  const callHandler = () => {
    if (Date.now() - baseTime > timeout) {
      baseTime = Date.now();
      handler();
    }
  };
  return window.setInterval(callHandler, 1000);
};

const absoluteClearInterval = (handle) => window.clearInterval(handle);

答案 6 :(得分:-2)

John Resig's blog中,据说计时器正在使用“挂钟”。我相信事件将在机器恢复后立即触发,因为setTimeout()不保证执行是特定的时间点,但是在指定的时间间隔后尽快执行。但是,我自己没有检查过。