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

发布于 2024-11-15 04:27:01 字数 287 浏览 3 评论 0原文

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

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

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

In a modern web browser, suppose I do a setTimeout for 10 minutes (at 12:00), and 5 minutes later put the computer to sleep, what should happen when the system wakes up again? What happens if it wakes up before the 10 minutes are up (at 12:09) or much later (at 16:00)?

The reason I'm asking is because I'd like to have a new authentication token requested every 10 minutes, and I'm not sure if the browser will do the right thing and immediately request a new token if it wakes up after a long time.

Clarifications: I don't wan't to use cookies - I'm trying to build a web service here; and yes, the server will reject old and invalid tokens.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

醉南桥 2024-11-22 04:27:01

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

我认为您不应该依赖 setTimeout/Interval 的准确性来处理时间关键的事情。对于 google chrome,我最近发现任何超时/间隔(即如果激活的选项卡失去焦点,则时间短于 1 秒)将减慢至每秒一次。

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

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

As far as I've tested, it just stops and resumes after the computer wakes up. When the computer awakes the setInterval/setTimeout is unaware that any time passed.

I don't think you should rely on the accuracy of setTimeout/Interval for time critical stuff. For google chrome I discovered recently that any timeout/interval (that is shorter than 1s) will be slowed down to once a second if the tab where it's activated looses focus.

Apart from that the accuracy of timeouts/intervals is dependent on other functions running etc. In short: it's not very accurate.

So using interval and timeouts, checking the time against a starttime within the function started by it would give you better accuracy. Now if you start at 12:00, the computer goes to sleep and wakes up at 16:13 or so, checking 16:13 against 12:00 you are certain you have to renew the token. An example of using time comparison can be found here

北音执念 2024-11-22 04:27:01

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

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

Compare current datetime against datetime when the page was loaded, like so:

//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);
逐鹿 2024-11-22 04:27:01

这是我的代码:

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

Here is my code :

<!doctype html>
<html>

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

</body>
<script>


</script>
</html>

I have taken three scenarios that might answer the question.

Scenario 1: At 00 Seconds click on 'Start Timer' button . At 25 seconds computer falls asleep.
At 1min 40 seconds wake up computer.
At 2mins Alert is displayed.

Scenario 2 : At 00 Seconds click on 'Start Timer' button . At 26 seconds computer falls asleep.
At 3 mins, I wakeup the computer. The Alert is displayed.

Scenario 3 : This one is truly astounding.

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

At 00 Seconds I click on 'Start Timer' button.
At around 1min 30 seconds the computer is on hibernate mode (my pc takes a minute to initiate hibernate)

At 8 mins I turn the laptop on.
At 10 mins exactly, the alert pops up.

PS: This is my first ever comment on Stack Exchange. I prefer to execute code and view results rather than infer from theory.
追星践月 2024-11-22 04:27:01

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

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

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

然而,安全不应该只是客户端的事情。确保如果使用旧的/无效的令牌,您的服务器会抛出错误,并且 Ajax 会做出适当的响应。

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

The behavior is based on both the browser and the operating system. The OS handle sleep and individual apps often don't account for it.

What will most likely happen is that the OS will come back up with the same time remaining on the timer as when it was shut down. The other possibility is that it won't fire at all.

If it is really a concern, you will probably want to be better safe than sorry and store a time stamp of when the token was initialized and use setInterval to check it periodically (say twice a minute).

However, security should not be just a client side thing. Make sure that your server throws an error if an old / invalid token is used and that the Ajax behaves appropriately in response.

[edit]
I agree with the other post that it might fire immediately on the next tick. Resig's blog post is very good.

謌踐踏愛綪 2024-11-22 04:27:01

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

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

由于 JavaScript 中的计时器基于 CPU 滴答,并且 CPU 处于睡眠状态,因此计时器会完全暂停并恢复为“因为不会发生任何事情”。

Behaviour of JavaScript timers (setTimeout) in several scenarios.

  1. When the thread is free and the timeout fires: The timer is fired immediately after the timeout. It might have certain imprecision of about 0-5 ms (typical scenario).
  2. When the thread is super busy (huge loop) long enough to pass the timer timeout: The timer will be executed immediately after the thread is freed.
  3. When there is an alert: Same behaviour as 2.
  4. When the thread is paused because our laptop went to sleep: I have seen several things. But most common is total inaccuracy and ignore of the time spent during sleeping.

Since timers in JavaScript are based on CPU ticks, and the CPU is sleeping, then the timer is completely paused and resumed as 'since nothing would have happen'.

不再见 2024-11-22 04:27:01

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

Based on Ben's answer, I created the following util. You can tweak the sampling duration, however I use it just like this for token refreshing:

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);
你怎么敢 2024-11-22 04:27:01

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

In John Resig's blog the timers are said to be using "wall clock". I believe that the events will fire immediately after the machine is resumed because setTimeout() doesn't guarantee an execution is a specific point in time but as soon as possible after the specified interval. However, I haven't checked it myself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文