以下代码在firefox和chrome之间打印出不同的结果
var start = Date.now()
var id = setInterval(function interval() {
var whileStart = Date.now()
console.log(whileStart - start)
while (Date.now() - whileStart < 250) {
}
}, 100)
setTimeout(function timeout() {
clearInterval(id)
console.log('timeout',Date.now() - start)
}, 400)
chrome 74打印:
100
351
605
timeout 855
firefox 67打印:
101
351
timeout 601
为什么?
添加setTimeout延迟,结果仍然不同。
var start = Date.now()
var id = setInterval(function interval() {
var whileStart = Date.now()
console.log(whileStart - start)
while (Date.now() - whileStart < 250) {
}
}, 100)
setTimeout(function timeout() {
clearInterval(id)
console.log('timeout',Date.now() - start)
}, 500)
答案 0 :(得分:2)
setTimeout将您的请求排入指定延迟后的第一个机会。一旦延迟过去并且调用堆栈为空,您的请求就会得到处理。这意味着时间会略有变化,具体取决于浏览器引擎的运行情况。
答案 1 :(得分:1)
这是因为Chrome's implementation of setInterval
确实纠正了每次通话之间的漂移。
因此,它实际上不会执行setTimeout(fn, 250)
。而不是在间隔的回调结束时再次盲目调用setTimeout(fn, max(now - 250, 0))
。
所以这给出了
t Firefox (no drift control) | Chrome (drift control)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––
0 schedule interval @100ms schedule interval @100ms
0 schedule timeout @400ms schedule timeout @400ms
100 exec interval callback exec interval callback
=> block 250ms => block 250ms
... ...
350 schedule interval @450ms schedule interval @350ms
(now + 100ms) (now + max(100ms - 250ms, 0))
350 exec interval callback
=> block 250ms
400 exec timeout callback ...
=> cancel interval ...
...
600 schedule interval @600ms
exec interval callback
=> block 250ms
...
850 schedule interval @850ms
exec timeout callback
=> cancel interval
请注意,最后一个间隔@600
实际上取决于首先安排的timeout
或interval
中的哪个间隔。
还要注意,Chrome的行为可能会在不久的将来成为标准行为:https://github.com/whatwg/html/issues/3151
答案 2 :(得分:0)
由于两个浏览器之间的代码差异而导致差异。
"use strict";
var start = Date.now()
setTimeout(function timeout() { // start the timeout first
clearInterval(id)
console.log('timeout',Date.now() - start)
}, 400)
var id = setInterval(function interval() {
var whileStart = Date.now()
console.log(whileStart - start)
while (Date.now() - whileStart < 250) {
}
}, 100)
简而言之,两个浏览器对间隔和计时器的超时处理的编码方式不同,在上述情况2中,Firefox似乎在间隔计时器调用之间增加了10ms的间隔(Section 7.5 of HTML 5.2中允许)。