是否在操作系统睡眠/暂停中定义了setTimeout的行为?

时间:2015-04-05 13:23:46

标签: javascript browser cross-browser

我设置setTimeout例如10s,在那10s期间,我暂停/睡眠PC。在醒来时,以下哪一项是正确的: -

  1. 确保超时
  2. 确保超时无法启动
  3. 超时可能会或可能不会触发。它是特定于浏览器的
  4. 重复的setInterval的相同问题。是否保证(不)继续。

3 个答案:

答案 0 :(得分:5)

简答

定义为在规范中执行。超时请求将进入排序队列并轮询,直到它被触发为止。如果系统在恢复时休眠,它将从中断处继续并恢复轮询。

长答案 可能比任何人都想知道

最近一次(2014年10月28日)working-draft of the Timer's Spec在w3写的回答时,它会触发...只要操作系统在进行过程中不会搞砸睡眠/暂停和唤醒/恢复(范围外部)。这更像是一个操作系统级别的问题,但就w3规范而言,最终会触发。

setInterval(...)setTimeout(...)都与浏览器的windowTimer对象实现的window接口不同。

在这两种情况下,客户端定义方法上下文所经历的间隔或超时请求timer initialization steps,其中它被添加到活动计时器列表任务返回> handle 。

进入活动计时器列表后,系统会将任务排队,以便在请求的持续时间或之后执行(等待具有更高优先级的其他任务)作为CPU负载)。如果任务无法保留CPU时间,它将轮询/等待直到可以。因此,如果系统在恢复时休眠,它将从中断处继续。

为了执行任务,句柄必须存在于活动计时器列表中。运行任务后,如果repeat标志设置为true(如果它是使用setInterval(...)创建的),任务将使用相同的参数重新创建并分配完全相同的处理。换句话说,它被添加回队列/列表,以便在下一个间隔或之后执行。

以下是Timer规范中关于系统从活动计时器列表中删除项目的唯一注释或注释:

  

一旦处理完任务,如果repeat标志为false,则可以安全地从活动计时器列表中删除句柄条目(在此点之后无法检测到条目的存在,因此它从技术上讲,这在某种程度上并不重要)

根据规范,当任务运行时它在list of active timers内,它将按预期触发。否则它会中止。回到我的第一点,如果操作系统在恢复任务继续轮询时在睡眠/暂停过程中没有弄乱。一旦它获得CPU时间,它的句柄应该仍然存在于活动计时器列表中,因此在处理后将执行。

答案 1 :(得分:4)

我刚用这个脚本测试过它:

<html>
<body>
<script>
var d = 120;
var start = new Date ();
document.write(start + " : sleeping for " + d + " seconds");
</script>
<div id='result'><div>
<script>
function cb() {
  var now = new Date ();
  document.getElementById("result").innerHTML = "" + Date () + " : callback fired after " + (now.getTime() - start.getTime()) / 1000 + " seconds";
};
window.setTimeout(cb, d * 1000);
</script>
</body>
</html>

我在Firefox 37.0.1和Chromium 41.0.2272.118(64位)中打开了该页面,然后暂停了我的机器几分钟。当我恢复时,即使计时器到期,两个浏览器也会等待几分钟。示例输出(机器在Wed 15 Apr 17:52:11 BST 2015处恢复):

Wed Apr 15 2015 17:49:13 GMT+0100 (BST) : sleeping for 120 seconds
Wed Apr 15 2015 17:53:47 GMT+0100 (BST) : callback fired after 273.705 seconds

答案 2 :(得分:0)

从我到目前为止所读到的,

  1. 保证会开火。
  2. 但是,延迟不能得到保证,可能取决于各种因素,因浏览器而异。 人们测试了这种行为。

    您可能需要查看以下cross-post。 John Resig也是interesting read