setTimeout的行为有点令人困惑, 我读过的所有资源表明,当没有指定延迟时,任务被附加到队列的末尾并在解释器没有剩下要做的时候执行(空队列?)。 但是,请采用以下示例:
setTimeout(function() { console.log('without delay!'); })
setTimeout(function () { console.log('with delay'); }, 1000);
var start = Date.now();
while (Date.now() < start + 3000) {} // block for 3 seconds
console.log('After wait');
根据上述前提,输出将为:
After wait
with delay
without delay
然而,输出是(在chrome和firefox中测试):
After wait
without delay
with delay
(请注意,当调用setTimeout(fn,1000)
时,一旦解释器在经过1秒后处于空闲状态,fn将立即执行,如果解释器仍然忙,则可能是1秒,5秒甚至是永久。)
上一个示例让我推断出setTimeout(fn)
,setTimeout(fn,0)
和setTimeout(fn,4)
之间没有差异(4毫秒是HTML5中的最小延迟),因为没有延迟的函数得到了在函数之前执行,已经过了1秒的延迟(这两个已准备好执行)
所以我的问题是他们是否等同于不? (在HTML5中)。
答案 0 :(得分:1)
根据W3 specification for timers,没有超时等于0,0等于4:
http://www.w3.org/TR/2011/WD-html5-20110525/timers.html#dom-windowtimers-settimeout:
...
4. Get the timeout,结果是超时。
5.如果当前正在运行的任务是由setTimeout()方法创建的任务,并且超时小于4,则将超时增加到4.
http://www.w3.org/TR/2011/WD-html5-20110525/timers.html#get-the-timeout:
当上述方法获取超时时,他们必须执行以下步骤:
让超时成为方法的第二个参数,如果省略参数则为零。
将ToString()抽象操作应用于超时,并将超时作为结果。 [ECMA262]
将ToNumber()抽象操作应用于超时,并将超时作为结果。 [ECMA262]
如果超时是无穷大值,非数字(NaN)值或负数,则超时为零。
舍入超时到最接近的整数,并将超时作为结果。
- 醇>
返回超时。
答案 1 :(得分:1)
你得到的完全符合预期。
当浏览器无事可做的时候,根本没有超时等待,当它没有正在运行任何东西的时候。
在您的代码被阻止三秒钟并退出代码后,浏览器可以自由开始处理事件,其中包括超时。由于两个超时都已过期,两个都将尽快执行,但是当第一个超时首先到期时,它将是要处理的事件队列中的第一个超时。
据Mozilla称,现代浏览器的最小延迟均为4毫秒:
&#34; 4毫秒由HTML5规范指定,并且在浏览器中保持一致 在2010年及之后发布&#34;
较旧的浏览器可能具有更高的最小延迟,例如10 ms。
该标准指定timeout参数的默认值为零,然后当然将其调整为最小延迟。
参考:http://www.w3.org/TR/2011/WD-html5-20110525/timers.html#get-the-timeout
因此,在没有超时或超时为0或4的情况下调用setTimeout
都是等效的。
即使在较旧的浏览器中,即使最小超时时间较长,它们也会有相同的结果。
答案 2 :(得分:0)
根据 mozilla ,如果您没有指定延迟,则每个浏览器都会设置最小值。因此,如果浏览器的最小值为4毫秒,那么0和4意味着相同。
连续的setTimeout()调用延迟小于“最小延迟”限制 被迫至少使用最小延迟。
答案 3 :(得分:0)
它们在功能上是等同的。如果你在SetTimeout中加一个0ms的延迟,它仍会等待4ms。
注意,在当前执行周期运行完成之前,SetTimeout的间隔不会开始计数。这就是为什么首先打印“无延迟”的原因。