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

IT技术 javascript settimeout
2021-03-08 02:33:15

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

我问的原因是因为我想每 10 分钟请求一个新的身份验证令牌,而且我不确定浏览器是否会做正确的事情并在很长时间后唤醒时立即请求一个新令牌时间。

说明:我不想使用 cookie - 我正在尝试在这里构建 Web 服务;是的,服务器将拒绝旧的和无效的令牌。

6个回答

据我测试,它只是在计算机唤醒后停止并恢复。我想这意味着会话取决于setTimeout/Interval从计算机入睡时开始的计数器滴答声。

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

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

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

the counter ticks on from the time the computer fell asleep.<- 我的经验也是如此。
2021-04-20 02:33:15
我刚刚为此创建了一个快速测试。FF 30 和 Chrome 35 可以在计算机恢复后立即触发长时间运行的超时。IE 10 重新加载页面。小提琴@ jsfiddle.net/Pegleg3941/8uhy8
2021-04-22 02:33:15
这也符合我的经验。
2021-04-28 02:33:15
我认为这可以更清楚地表达:当计算机唤醒时,setInterval/setTimeout 不知道任何时间过去了。
2021-05-12 02:33:15
截至 2017 年(Chrome 61),这种从睡着状态继续计数器的行为没有改变。
2021-05-14 02:33:15

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

//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);
在我的情况下,只有当用户在最后一小时处于活动状态且未空闲时,我才必须获取新令牌。因此,从服务器令牌中获取 1 小时后过期,但在此之前,我必须获取新令牌并更新 localStorage。如果用户处于非活动状态,则显示会话过期消息,否则静默获取新令牌
2021-04-23 02:33:15
内部setInterval()的原因是什么?为什么是5秒?
2021-04-27 02:33:15
这是一个很好的解决方案。对我来说效果很好 - 谢谢。
2021-05-06 02:33:15

这是我的代码:

<!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.

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

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

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

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

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

关于安德鲁的编辑:它可能会在唤醒时立即触发,但这取决于浏览器。
2021-04-21 02:33:15
他们可能正在使用带有时间戳的 cookie。我正在尝试使用 cookieless 服务,因此问题。
2021-04-22 02:33:15
你实际上让我思考在这种情况下我自己的应用程序将如何表现......这确实是一个好问题。我几乎想登录我的银行并尝试看看他们的行为。
2021-05-04 02:33:15
例如,IE 10 会重新加载页面。
2021-05-08 02:33:15
服务器将拒绝旧令牌......我试图不向客户端显示不必要的错误......
2021-05-09 02:33:15

根据 Ben 的回答,我创建了以下实用程序。您可以调整采样持续时间,但是我像这样使用它来刷新令牌:

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