js事件循环

60 阅读2分钟

nodejs事件循环

nodejs中Event Loop

  1. timer - setTimeout和setInterval回调函数执行阶段
  2. pending callbacks - OS级别的回调,例如TCP链接错误等
  3. idle/prepare - nodejs内部使用
  4. poll - 各种非timer阶段的回调函数
  5. check - setImmediate()的回调函数
  6. close - 注册close事件的回调函数

process.nextTick以及Microtask

nextTick以及Microtask中的回调函数会在node初始化后进入事件循环前执行,在此过程中回清空nextTick和微任务队列中的任务,另外值得注意的是nextTick优先级高于微任务,我们看到有些文章将nextTick回调算入微任务。在此过程中会不断迭代nextTick和微任务队列直到清空为止,因此如果递归向两个队列中添加任务会导致“事件循环饥饿”。
在进入事件循环后,nextTick和微任务队列执行出现在每个回调函数执行结束后(注意此特性跟node版本有关,node v11.15.0之前是在每个阶段执行结束后才进入微任务对列迭代执行)。

poll阶段

进入poll阶段有两种情况:

  1. 如果poll队列不为空,则迭代执行直到os限制的最大时间片用完或者执行完队列
  2. 如果poll队列为空,则查看immediate队列,如果有任务则进入check阶段,另外每当队列为空时,node会检测timer队列中是否有任务,如果timer有新的任务则会通过check阶段再进入timer阶段。如果poll为空且immediate和timer队列为空则会阻塞在此阶段。

浏览器中事件循环

浏览器中分为任务队列和微任务队列,执行流程为:

  1. 从任务队列取一个任务执行
  2. 判断微任务队列是否为空,迭代执行清空微任务队列
  3. 任务队列和微任务队列结束后执行渲染任务

注意js执行和layout和paint在主线程执行,因此js的执行会阻塞渲染任务。

有哪些微任务?

  1. promise.then
  2. MutationObserver

requestAnimationFrame,setTimeout,setInterval方法为宏任务。