setTimeout 对比睡眠模式

Posted

技术标签:

【中文标题】setTimeout 对比睡眠模式【英文标题】:setTimeout Vs. sleep mode 【发布时间】:2020-06-15 21:29:04 【问题描述】:

根据我在几个 SO 答案中的理解,如果计算机在调用 setTimeout 后进入睡眠模式,则应忽略睡眠期。

例如:

t0:setTimeout(foo, 30000); t0+20s: 电脑进入睡眠模式 t0+40s: 电脑退出睡眠模式 t0+50s: foo 被调用

但是,我的测试显示以下行为:

t0:setTimeout(foo, 30000); t0+20s: 电脑进入睡眠模式 t0+40s:计算机退出睡眠模式并调用foo

我的理解是,当计算机唤醒时,如果在休眠期间会触发超时,则立即触发,否则在t0+[超时值]时触发。

那么预期的行为是什么? 所有浏览器和操作系统都一样吗?

我的一个测试(在 Windows 10 上使用最新版本的 Chrome):https://codepen.io/robloche/pen/GRJvEJB

【问题讨论】:

setTimeout 的一般“定义”是“在给定超时后尽快尽最大努力”。因此,一旦计算机再次唤醒,它就会触发它是有意义的。我不确定规范中是否明确涵盖了这种边缘情况,因此这里的每个实现都可能不同。 据我所知,setTimeout 将尝试遵守原始睡眠期,否则它将排队触发。 IOW:如果你设置了 1 分钟的 setTimeout,进入睡眠 30 秒,然后恢复,30 秒后超时将触发,但如果你进入睡眠 2 分钟,超时将在恢复时立即触发。 这取决于如果计算机进入睡眠状态,实现用于超时的时钟是否也暂停/睡眠。但是 afaik 所有当前的实现都使用实际时间作为超时使用的时钟的参考,所以你的第二个例子是预期的结果。 My understanding is that when the computer wakes up, if the timeout would have been triggered during the sleep period, it's instantly triggered, otherwise, it's triggered at t0+[timeout value].?:是的 @Keith 这就是我观察到的,但它似乎与我在这里读到的不同:***.com/questions/6346849/… 当然,但是“30000”基本上是指“在 30 秒内”,而不是“通过每秒减去 1 来倒数到 30”,所以观察到的行为非常有意义。 【参考方案1】:

总结上面的cmets:

我描述的行为似乎对每个人都有意义。 我仍然不确定它是否符合规范或所有浏览器都以这种方式实现它。

我最初的问题是更新身份验证令牌,我最终得到了一个不使用setTimeout 的解决方案(感谢https://***.com/a/6347336/603393):

获得令牌后,我计算并存储下一个续订日期 我使用setInterval 定期检查下一个续订日期是否过去。

这样,计算机在下一个续订日期前 1 秒或 36 小时后唤醒都没有关系。

【讨论】:

以上是关于setTimeout 对比睡眠模式的主要内容,如果未能解决你的问题,请参考以下文章

当 Windows 进入睡眠模式然后唤醒时 setTimeout 不起作用

javascript 超时/睡眠使用 setTimeout()

js setTime()详解

当 iPhone/Android 进入睡眠状态时,JavaScript 执行(settimeout 等)会发生啥?

为啥C没有像javascript中的setTimeout这样的非阻塞睡眠功能

是否定义了跨操作系统睡眠/挂起的 setTimeout 行为?