Skip to content

事件轮询(Event Loop)

事件触发线程管理的任务队列是如何产生的呢?事实上这些任务就是从JS引擎线程本身产生的,主线程在运行时会产生执行栈,栈中的代码调用某些异步API时会在任务队列中添加事件,栈中的代码执行完毕后,就会读取任务队列中的事件,去执行事件对应的回调函数,如此循环往复,形成事件循环机制。JS中有两种任务类型:微任务(microtask)和宏任务(macrotask),在ES6中,microtask称为 jobs,macrotask称为 task:

  • 宏任务: script (主代码块)、setTimeout 、setInterval 、setImmediate 、I/O 、UI rendering
  • 微任务:process.nextTick(Nodejs) 、Promise 、Object.observe 、MutationObserver

Node.js中Event Loop和浏览器中Event Loop有什么区别?

Node.js中宏任务分成了几种类型,并且放在了不同的task queue里。不同的task queue在执行顺序上也有区别,微任务放在了每个task queue的末尾:

  • setTimeout/setInterval 属于 timers 类型;
  • setImmediate 属于 check 类型;
  • socket 的 close 事件属于 close callbacks 类型;
  • 其他 MacroTask 都属于 poll 类型。
  • process.nextTick 本质上属于 MicroTask,但是它先于所有其他 MicroTask 执行;
  • 所有 MicroTask 的执行时机在不同类型的 MacroTask 切换后。
  • idle/prepare 仅供内部调用,我们可以忽略。
  • pending callbacks 不太常见,我们也可以忽略。