给setInterval或setTimeout传递一个分数延迟是否安全?

Is it safe to pass setInterval or setTimeout a fractional delay?

本文关键字:一个 延迟 是否 安全 setTimeout setInterval      更新时间:2023-09-26

我知道由于浏览器计时器不准确,这种差异目前可以忽略不计,但是为了了解情况:是否有任何浏览器支持setInterval和setTimeout,但要求将它们作为延迟传递一个整数值?

或者,用例子重新表述,是这样的:

setInterval(animate,50/3);

是跨浏览器兼容的吗?

setInterval(animate,17);

绝对安全。

(正如RobG指出的那样,我没有提供DOM/JS桥规则本身的参考,他敦促谨慎。据我所知,我相信——但没有确凿的证据——ToInteger 是接口桥的部分。这里是一个jsfiddle,显示超时作为字符串,浮点数和整数(与JS中的float类型相同)传递,在FF8和IE9中工作良好。欢迎反馈。)

这是因为 DOM接口只接受整数作为setTimeout/setInterval中的延迟——是的,这些是在DOM中定义的,而不是在ECMAScript中。延迟值首先被适当地转换为整数值(在这方面,调用[JS-internal] ToInteger函数执行截断*)。

然而,示例数字实际上会产生略有不同的结果(尽管可能不太明显):-)

这是因为50/3 (16.66andsomemore -> 16)和17 指定了不同的超时

幸福的编码。


除特殊情况外,

* ToInteger定义为sign(number) * floor(abs(number))。参见第5版ECMAScript规范第9.4节

Javascript在浮点数和整数之间没有真正的区别,在底层是相同的数据类型。11.0在内存中是位对位的。

因此,你可以传递一个小数值而不会有任何实际问题。这是完全有效的JavaScript。即使它确实需要一个整数,它也更有可能简单地、无声地为你舍入它。

但不要指望它是准确的!由于回调调度的低粒度,0.1, 1甚至4.87的时间都可能在非常接近的时间内触发。

我认为第二个参数将作为一个表达式计算,只要它返回一个数字就可以工作。它似乎工作在铬。只要确保你没有除以0 !

这些函数期望毫秒。我怀疑你能期望任何精度超过10ms,并且浏览器强制计时器限制。

Firefox不介意十进制值。你可以在任何你感兴趣的浏览器中进行测试。

这取决于,取决于参数delay是否转换为整数,是否使用累积延迟[^1]策略,取决于您是否使用电池供电的设备和省电模式。

测试setInterval,延迟1000/15~=66.6667,持续时间60s,页面始终可见(不切换到背景,不关闭屏幕),使用以下浏览器:

  • Windows Chrome 108
  • Android Chrome 107iOS Safari 16.0
  • Windows Firefox 107
  • Android Firefox 108 Beta

参见CodePen setInterval实际间隔测试

setInterval的实际平均间隔时间

<表类> 场合'平台Windows Chrome Android Chrome macOS Safari iOS Safari Windows Firefox Android Firefox tbody> <<tr>页面可见道明> 66.01 66.69 78.45 66.67 page可见(电池省电模式)66.01 66.01 89.76 78.36 66.68 页面隐藏td> 页面隐藏(电池省电模式)tbody>