【JS】setTimeout最小间隔4ms的问题
setTimeout(()=>{console.log(5)},5)setTimeout(()=>{console.log(4)},4)
setTimeout(()=>{console.log(3)},3)
setTimeout(()=>{console.log(2)},2)
setTimeout(()=>{console.log(1)},1)
setTimeout(()=>{console.log(0)},0)
为什么输出1,0,2,3,4,5,不是说setTimeout最小间隔4ms吗?
运行环境Chrome/Safari
在Firefox下为0,1,2,3,4,5
回答
// https://github.com/nodejs/node/blob/v8.9.4/lib/timers.js#L456if (!(after >= 1 && after <= TIMEOUT_MAX))
after = 1; // schedule on next tick, follows browser behavior
设置最低1ms的行为是为了向浏览器行为看齐。
虽然有4ms的限制,但是是存在条件的.详见MDN英文文档
setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。
执行完setTimeout(()=>{console.log(1)},1)
的时候一个毫秒已经过去了, 而且console.log(1)
已经先进入了事件循环中, 于是就console.log(
)`
setTimeout的第二个参数,不得低于4毫秒,如果低于这个值,就会自动增加,根据浏览器和当前环境不同,最低时间间隔也不一样,浏览器执行的顺序应该和浏览器当前状态有关系,我在firebox执行的结果是0 1 5 4 3 2
复现楼主问题:
setTimeout(()=>{console.log(5)},5) setTimeout(()=>{console.log(4)},4)
setTimeout(()=>{console.log(3)},3)
setTimeout(()=>{console.log(2)},2)
setTimeout(()=>{console.log(1)},1)
setTimeout(()=>{console.log(0)},0)
打印的日志:
下面是补充点我自己发现的信息
setTimeout(()=>{console.log(5)},5) setTimeout(()=>{console.log(4)},4)
setTimeout(()=>{console.log(3)},3)
setTimeout(()=>{console.log(2)},2)
setTimeout(()=>{console.log(0)},0)
setTimeout(()=>{console.log(1)},1)
当是这种顺序的时候,chrome和safari俩个浏览器下会打印
6个setTimeout
在本次event loop
依次将回调函数放入task
队列,在未来等待event loop
检测到了指定时间时执行,先压入的回调先执行;出现不同的执行顺序,可以理解为,当下次的event loop
执行时,如果已经超过1ms
,就先执行console.log(1)
的回调(因为队列中它更靠前);而如果未超过1ms,则执行console.log(0)
的回调。
见过一篇v8源码分析里面说的 chrome对timeout的实现最小是1ms 所以无论延时设置1和0 都仿佛同步代码按顺序执行 4ms指的是多层timeout嵌套情况下 最小4ms 文章我找不到了
最小间隔4ms的说法是不准确的,或者说是有前提条件的,请看HTML标准:
11. If nesting level is greater than 5, and timeout is less than 4, then set timeout to 4.
也就是说,循环嵌套超过5层的,并且延迟不到4ms,才会变成4ms
标准是这么规定的,各个浏览器具体怎么定义的,我没有亲测~
chrome 下是因为设置 1ms 或者是 0ms 都是 1ms,所以输出是 1, 0 而不是 0, 1
源码地址
double intervalMilliseconds = std::max(oneMillisecond, interval * oneMillisecond);
参考文章地址:Event Loop的规范和实现
以上是 【JS】setTimeout最小间隔4ms的问题 的全部内容, 来源链接: utcz.com/a/82841.html