浏览器 event loop

128 阅读2分钟

一 什么是event Loop?

先来看一段代码

console.log('script start')
setTimeout(() => {
    conso.log('timeOut')
}, 0)
conosle.log('script end')

输出结果: 
script start 
script end
timeOut
    

为什么 timeOut 在最后输出?因为这里涉及到了jscode在浏览器中运行时的机制。

在执行我们的js code时, 先由上至下顺序执行,行程一个执行栈, 但是遇到异步任务时, 就会暂缓执行,先将他们挂起, 待异步任务
有了结果, 就将它们添加到指定的任务队列(宏任务或微任务),等到执行栈为空, js线程就会从微任务队列取出一个微任务去执行
(如果存在微任务),等到微任务队列为空时, 就会去宏任务队列取出一个任务执行, 宏任务中如果产生微任务, 则会将产生的微任务
放入微任务队列, 直至微任务全部执行完成(微任务队列为空), 再次从宏任务队列取出一个任务执行, 一直循环, 至此形成了一个
事件的循环
浏览器中的宏任务包括: setinterval setTimeout requestAnimationFrame
微任务包括: promise.then mutationObserve
 

浏览器中的v8引擎是一个多线程引擎, 主要包括:

  1. 渲染线程(渲染页面, js线程可以操作dom,会影响渲染,所以渲染线程和js线程是互斥的)
  2. js线程(执行js code)
  3. 定时器线程(setTimeout 等)
  4. http线程(ajac请求)
  5. 事件触发线程(用户交互)

事件的循环过程中如果有用户的点击事件,会在宏任务队列中添加一个任务, 如果队列中的任务执行时间过长,就会导致用户的点击事件的回调延迟执行, 因为浏览器的渲染大概是16ms一帧, 用户就会感觉到页面卡顿