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

What happens to setTimeout when the computer goes to sleep?

本文关键字:setTimeout 什么 状态 计算机      更新时间:2023-09-26

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

我之所以这么问,是因为我希望每10分钟请求一次新的身份验证令牌,而且我不确定浏览器是否会做正确的事情,如果在很长一段时间后醒来,会立即请求一个新的令牌。

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

就我所测试的而言,它只是在计算机唤醒后停止并恢复。当计算机唤醒时,setInterval/setTimeout不知道已经过了任何时间。

我认为你不应该依赖setTimeout/Interval的准确性来处理时间关键的事情。对于谷歌chrome,我最近发现,如果激活它的选项卡失去焦点,任何超时/间隔(小于1秒)都会减慢到每秒一次。

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

因此,使用interval和timeouts,将时间与它启动的函数中的starttime进行比较,可以获得更好的准确性。现在,如果您在12:00开始,计算机将进入睡眠状态,并在16:13左右醒来,将16:13与12:00进行比较,您确定必须续订令牌。使用时间比较的示例可以在这里找到

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

//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);

这是我的代码:

<!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分钟时,我唤醒了电脑。此时将显示Alert(警报)。

场景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.

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

最有可能发生的情况是,操作系统将在计时器上返回与关闭时相同的剩余时间。另一种可能性是它根本不会开火。

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

然而,安全不应该仅仅是客户端的事情。如果使用了旧的/无效的令牌,请确保服务器抛出错误,并且Ajax的响应行为正确。

[编辑]我同意另一个帖子,它可能会在下一次点击时立即启动。Resig的博客文章非常好。

JavaScript计时器(setTimeout)在几种场景中的行为。

  1. 当线程空闲并且超时触发时:计时器在超时后立即触发。它可能具有大约0-5毫秒的某些不精确性(典型情况)
  2. 当线程超忙(巨大循环)足够长以通过计时器超时时:线程释放后,计时器将立即执行
  3. 出现警报时:行为与2相同
  4. 当线程由于我们的笔记本电脑进入睡眠状态而暂停时:我看到了一些事情。但最常见的是完全不准确,忽略了睡觉的时间

由于JavaScript中的计时器是基于CPU的滴答声,并且CPU正在休眠,因此计时器将完全暂停并恢复为"因为什么都不会发生"。

基于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);

在John Resig的博客中,计时器被称为使用"挂钟"。我相信事件会在机器恢复后立即触发,因为setTimeout()不能保证执行是在特定的时间点,而是在指定的时间间隔后尽快执行。但是,我自己还没有检查过。