2012-03-10 80 views
40

我想提出setTimeout的最小毫秒值是多少?

var minValue = 0; 
if (typeof callback == 'function') { 
    setTimeout(callback, minValue); 
} 

此代码时,我实现与JavaScript回调函数。

但我发现,现代浏览器和一些老的浏览器

有不同的最小超时值。

我知道零不能是最小值。

会为

现代浏览器和一些老的浏览器兼容性问题是什么的setTimeout的最小值?

+6

[查看MDN。](https://developer.mozilla.org/en/DOM/window.setTimeout#Minimum_delay_and_timeout_nesting)。尽管你指定的时间永远不可靠。 – pimvdb 2012-03-10 14:31:04

+1

你可以随时写一个测试... – 2012-03-10 14:31:43

+0

@BradChristie你怎么UnitTest JavaScript代码? TDD? – InspiredJW 2012-03-10 16:00:31

回答

39

我认为10将是所有浏览器中最可靠的最小值,因为我已经看过很多使用它的代码。

然而,4ms is the minimum for HTML5

事实上,4ms的由HTML5规范的规定,并且是跨在2010年及以后发布的浏览器是一致的。在(Firefox 5.0/Thunderbird 5.0/SeaMonkey 2.2)之前,嵌套超时的最小超时值为10毫秒。

+0

对不起,这不是(不再?)真实。除了注释外,我无法在[标准](http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers)中找到关于4ms延迟的声明: “注意:定时器可以嵌套,但在5个这样的嵌套定时器之后,时间间隔必须至少为4毫秒。”进一步的好奇心让我在谷歌群体上看到了[这篇伟大的文章](https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/Hn3GxRLXmR0/XP9xcY_gBPQJ)铬。 – 2013-12-10 21:22:08

+0

@TobbeBrolin无论它在实现中是否为真,[它仍然在规范中](http://www.w3.org/TR/html5/webappapis.html#timers):“如果当前运行的任务是由setTimeout()方法创建,并且超时值小于4,然后将超时值增加到4.“ – apsillers 2014-01-15 02:29:49

+2

@TobbeBrolin但是,我没有看到WHATWG规范中反映的语言。看起来像W3C和​​WHATWG不同意这一点。 – apsillers 2014-01-15 12:59:14

9

现代浏览器中的最小值为4ms(截止到HTML5),在此之前为10ms。请注意,这些时间绝不是100%准确的。

3

本文测试的Firefox,Safari和Opera和图形性能图表:

http://ejohn.org/blog/analyzing-timer-performance/

Firefox 2中,Opera和Safari都具有10毫秒的延迟

底部窗口

对于旧版本的浏览器,您可以进行类似该文章中的测试。我刚刚在IE6上运行了一段时间内使用10ms间隔的测试,并且我得到了55ms的平均值setIntervalsetTimeout似乎低于35ms

我在Chromium中运行测试,得到〜11ms 10ms超时的平均值。我以4ms和1ms的间隔尝试了它,并获得了〜4.5ms。另外,请记住,这些数字可能因操作系统而异。

如果你有兴趣,这里的测试代码:

<script> 
// number of times to call setTimeout before calculating average 
var ITERATIONS = 200; 

window.onload = function() 
{ 
    testTimeout(10, +new Date, 0, 0); 
} 

// calls setTimeout repeatedly at a specified interval, tracking the amount 
// of time that passes between successive calls 
function testTimeout(interval, last, sum, ii) 
{ 
    var time = +new Date; 
    var difference = time - last; 
    sum += difference; 
    if (ii % ITERATIONS == 1) 
    { 
     document.body.innerHTML = sum/ITERATIONS; 
     sum = 0; 
    } 
    window.setTimeout(
     function() { 
      testTimeout(interval, time, sum, ii + 1) 
     }, interval); 
} 
</script> 
3

setTimeout是最有可能调用sleep or Sleep system call

实际的机制,包括最小的毫秒数,setTimeout是专有和/或系统相关的,因为它们不在官方的ECMA规范中。这取决于你的Javascript运行时间,以及你正在运行它的系统。鉴于您的Javascript运行时不会增加很多开销,最小的毫秒数取决于操作系统和硬件的时间片分辨率。最短的“睡眠时间”时间通常是您的系统scheduling algorithm为进程分配另一个timeslice所花费的时间。

在Windows(XP后)为例,the documentation for the sleep system call透露:

零值会导致线程在其 时间片的剩余部分放弃任何其他线程准备运行。如果没有其他线程准备运行,该函数立即返回,并且线程继续执行。

这意味着,某些极为罕见的条件下,在没有其他进程当前正在等待的hardware thread您的JavaScript脚本运行时间process下运行,它可能会立即继续,这取决于你的Javascript如何运行时间已实施。虽然你可能不会经常观察这种情况:)

+1

真正的答案 – Pinal 2015-05-14 11:39:48

+4

我必须承认这个答案并不能说服我,因为它与我所知道的关于javascirpt(主要是)单线程基于事件的执行的知识不匹配。你能指出任何引用说任何js实现调用'sleep'吗? – Davide 2015-12-11 10:35:04

+0

*“它可能会立即继续,这取决于您的Javascript运行时间的实现方式”* - 如果运行时正确实现,超时将不会运行,直到当前代码执行完毕 - 即使您指定时间为0仍然会排队。 – nnnnnn 2016-07-20 14:17:05