setTimeout
1 | function task() { |
setTimeout 是一个异步的所以会先 执行 console 这个同步任务。如果修改代码如下,会发现执行时间远远超过预定的时间
1 | setTimeout(() => { |
执行过程如下:
task函数进入到event table里面注册计时- 然后主线程执行
sleep函数,比较慢。计时仍在继续 - 3 秒到了。
task函数进入event queue但是主线程仍然没有走完 - 终于过了
10000ms之后主线程走完了,task函数进入到主线程执行。所以可以看出其真实的时间是远远大于 3 秒
说明几个容易困惑的问题
setTimeout(fn, 0), fn是不是立刻执行?不一定,要看主线程内的命令是否已经执行完了。这个任务会在主线程最早可得的空闲时间执行,就是主线程的任务执行结束之后立马执行。
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于 4 毫秒,如果低于这个值,就会自动增加。在此之前,老版本的浏览器都将最短间隔设为 10 毫秒。另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常不会立即执行,而是每 16 毫秒执行一次。Ajax请求是否异步?Ajax异步请求内容的时候是异步的,当请求完成后,会触发请求完成的事件,然后把回调函数放入callback queue,等到主线程执行该回调函数时还是单线程的。界面渲染线程是单独开辟的线程,是不是
DOM一变化,界面就立刻重新渲染?如果
DOM一变化,界面就立刻重新渲染,效率必然很低,所以浏览器的机制规定界面渲染线程和主线程是互斥的,主线程执行任务时,浏览器渲染线程处于挂起状态。