5
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

2018-05-22 提问
6 个回答
1
// https://github.com/nodejs/node/blob/v8.9.4/lib/timers.js#L456

if (!(after >= 1 && after <= TIMEOUT_MAX))
  after = 1; // schedule on next tick, follows browser behavior

设置最低1ms的行为是为了向浏览器行为看齐。

虽然有4ms的限制,但是是存在条件的.详见MDN英文文档

clipboard.png

0
setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。

执行完setTimeout(()=>{console.log(1)},1)的时候一个毫秒已经过去了, 而且console.log(1)已经先进入了事件循环中, 于是就console.log()`

参考:setTimeout运行机制

0

setTimeout的第二个参数,不得低于4毫秒,如果低于这个值,就会自动增加,根据浏览器和当前环境不同,最低时间间隔也不一样,浏览器执行的顺序应该和浏览器当前状态有关系,我在firebox执行的结果是0 1 5 4 3 2

0

复现楼主问题:

  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俩个浏览器下会打印
图片描述

0

6个setTimeout在本次event loop依次将回调函数放入task队列,在未来等待event loop检测到了指定时间时执行,先压入的回调先执行;出现不同的执行顺序,可以理解为,当下次的event loop执行时,如果已经超过1ms,就先执行console.log(1)的回调(因为队列中它更靠前);而如果未超过1ms,则执行console.log(0)的回调。

0

见过一篇v8源码分析里面说的 chrome对timeout的实现最小是1ms 所以无论延时设置1和0 都仿佛同步代码按顺序执行 4ms指的是多层timeout嵌套情况下 最小4ms 文章我找不到了

撰写答案

推广链接