向 setInterval 或 setTimeout 传递小数延迟是否安全?

发布于 2024-12-20 11:30:35 字数 252 浏览 2 评论 0原文

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

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

setInterval(animate,50/3);

像这样跨浏览器兼容吗?

setInterval(animate,17);

I know that the difference would currently be negligible due to inaccurate browser timers, but for the sake of knowledge if nothing else: is there any browser that supports setInterval and setTimeout, but requires that they be passed an integer value as a delay?

Or, rephrased with examples, is this:

setInterval(animate,50/3);

as cross-browser compatible as this?

setInterval(animate,17);

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

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

发布评论

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

评论(5

究竟谁懂我的在乎 2024-12-27 11:30:35

这是绝对安全的。

(正如 RobG 指出的那样,我没有提供 DOM/JS 桥接规则本身的参考,他敦促谨慎行事。FWIW,我相信 - 但没有提到最终的声明 - ToInteger 接口桥的一部分。这是一个 jsfiddle 显示超时传递为一个字符串,一个float 和一个整型(与 JS 中的 float 类型相同),在 FF8 和 IE9 中运行良好。欢迎反馈。)

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

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

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

快乐编码。


*ToInteger 定义为 sign(number) * Floor(abs(number)),特殊情况除外。请参阅第 5 版 ECMAScript 规范第 9.4 节。

It is perfectly safe.

(As RobG points out, I haven't provide a reference to the DOM/JS bridge rules themselves and he urges caution. FWIW, I believe -- but have no reference to conclusively state -- that ToInteger is part of the interface bridge. Here is a jsfiddle showing the timeout being passed as a string, a float, and an integral (same type as float in JS) which works fine in FF8 and IE9. Feedback welcome.)

This is because the DOM interface only accepts integers for the delay in setTimeout/setInterval -- yup, these are defined in the DOM, not in ECMAScript. The delay value is appropriately converted to an integral value first (and in this aspect the [JS-internal] ToInteger function is invoked which performs a truncation*).

However, the example numbers will actually yield slightly different results (although it might not be noticable) :-)

This is because, 50/3 (16.66andsomemore -> 16) and 17 specify different timeouts.

Happy coding.


*ToInteger is defined as sign(number) * floor(abs(number)), excluding special cases. See Section 9.4 of the 5th Edition ECMAScript specification.

一百个冬季 2024-12-27 11:30:35

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

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

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

Javascript makes no real distinction between floating point numbers and integers, and are the same data type under the hood. 1 and 1.0 are bit for bit identical in memory.

Therefore yes, you can pass a fractional value without any real issues. It's perfectly valid JavaScript. And even if it did require an integer, it's more likely it would simply and silently round it down for you.

But don't expect it to be accurate! A time of 0.1, 1 or even 4.87 will all probably fire at very close to the same time due to the low granularity of the callback scheduling.

一指流沙 2024-12-27 11:30:35

我想第二个参数将被计算为一个表达式,只要它返回一个数字就可以工作。它似乎可以在 Chrome 中使用。只要确保你没有被零除即可!

I would imagine that the second parameter would be evaluated as an expression and as long as it returns a number it will work. It seems to work in chrome. Just make sure you don't divide by zero!

你的他你的她 2024-12-27 11:30:35

这些函数需要毫秒。我怀疑您可以期望任何大于 10 毫秒的精度,并且浏览器强制执行计时器限制

Firefox 不介意小数值。您可以在您感兴趣的任何其他浏览器中进行测试

These functions expect milliseconds. I doubt you could expect any accuracy greater than 10ms, and browsers enforce timer restrictions.

Firefox doesn't mind decimal values. You can test in any other browsers you're curious about.

云归处 2024-12-27 11:30:35

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

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

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

请参阅 CodePen setInterval 实际间隔测试

的实际平均间隔刻度

setInterval场合\平台Windows ChromeAndroid ChromemacOS SafariiOS SafariWindows FirefoxAndroid Firefox
页面可见66.0166.0166.6978.4566.67
页面可见(节省电池电量)模式)66.0166.0189.7678.3666.68
页面隐藏
页面隐藏(电池省电模式)

根据上面的测试结果,我可以看出:

Chrome的setInterval会floor()参数延迟,但它使用自校准[^2]策略来保持tick目前,及时忽略节电模式。

Safari 的 setInterval 取决于低功耗模式的状态,它支持分数延迟并使用自校准策略来及时保持滴答声,但如果低功耗模式打开,则会发生累积延迟效应,使得分数延迟无济于事。

Windows Firefox 的 setInterval 采用累积延迟策略,而 Android Firefox 的 setInterval 采用自校准策略。

脚注:

[^1]:累积延迟意味着平均刻度间隔将明显大于参数延迟

[^2]:自校准意味着平均刻度间隔可以非常接近参数延迟

It depends, depends on whether argument delay is converted to integer, whether cumulative-delay[^1] strategy is used, depends on whether you are using a battery-powered device and power saving mode is on.

Test setInterval with 1000/15~=66.6667 delay, 60s duration, keep page visible all the time (without switching to background, without screen off), with the following browsers:

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

see CodePen setInterval actual interval test

Actual average interval tick of setInterval

occasion \ platformWindows ChromeAndroid ChromemacOS SafariiOS SafariWindows FirefoxAndroid Firefox
page visible66.0166.0166.6978.4566.67
page visible (battery power saving mode)66.0166.0189.7678.3666.68
page hidden
page hidden (battery power saving mode)

According to the test result above, what I can tell is:

Chrome's setInterval will floor() argument delay, but it use self-calibration[^2] strategy to keep ticks in time, currently ignores Batter Saver Mode.

Safari's setInterval depends on state of Low Power Mode, it supports fractional delay and use self-calibration strategy to keep ticks in time, but if Low Power Mode is on then cumulative-delay effect happens such that a fractional delay just doesn't help.

Windows Firefox's setInterval uses cumulative-delay strategy,while Android Firefox's setInterval uses self-calibration strategy.

Footnote:

[^1]: cumulative-delay means average tick interval will be obviously larger than argument delay.

[^2]: self-calibration means average tick interval can be very close to argument delay.

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