# 浏览器和 Node 事件循环的区别

【浏览器】

关于浏览器的事件循环机制,我总结了一篇较详细的博客:博客地址 (opens new window)

关于微任务和宏任务在浏览器的执行顺序是这样的:

  • 执行一只task(宏任务)
  • 执行完micro-task队列 (微任务)
  • 如此循环往复下去

浏览器事件循环机制

  • 宏任务一般包括:整体代码script,setTimeout,setInterval、setImmediate、I/O 操作、UI 渲染等。
  • 微任务一般包括:new Promise().then(回调)、MutationObserver(html5新特性) 、process.nextTick等。

【Node】

Node的事件循环是libuv实现的。

libuv库是多平台C库,提供对基于事件循环的异步I/O的支持。它支持epoll、kqueue、Windows的IOCP和Solaris的事件端口。它主要设计用于Node.js,但也可用于其他软件项目如Julia或pyuv等。

Node事件循环机制如下:

Node事件循环机制

宏任务的执行顺序如下:

  • timers定时器:本阶段执行已经安排的 setTimeout() 和 setInterval() 的回调函数。
  • pending callbacks待定回调:执行延迟到下一个循环迭代的 I/O 回调。
  • idle, prepare:仅系统内部使用。
  • poll 轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,它们由计时器和 setImmediate() 排定的之外),其余情况 node 将在此处阻塞。
  • check 检测:setImmediate() 回调函数在这里执行。
  • close callbacks 关闭的回调函数:一些准备关闭的回调函数,如:socket.on('close', ...)。

微任务和宏任务在Node的执行顺序(Node10之前和Node11以后是不一样的):

(1)Node10之前

  • 执行完一个阶段的所有任务
  • 执行完nextTick队列里面的内容
  • 然后执行完微任务队列的内容

(2)Node11以后

  • 和浏览器的行为统一了,都是每执行一个宏任务就执行完微任务队列。