返回

JavaScript 执行机制:揭秘宏任务、微任务和事件循环 (Event Loop)

前端

我们经常谈到 JavaScript(简称 JS)是单线程编程语言,这意味着同一时间只有一个代码段可以在主线程上执行。对于需要长时间等待的任务,它们会阻塞线程。为了解决这个问题,JS 引入了宏任务和微任务的概念,并通过事件循环 (Event Loop) 机制协调其执行。

宏任务和微任务

  • 宏任务: 包括脚本、setTimeout、setInterval、I/O 操作等。这些任务会在当前所有同步任务执行完毕后加入宏任务队列。
  • 微任务: 包括 Promise、MutationObserver、process.nextTick 等。这些任务会在当前所有同步任务和宏任务执行完毕后加入微任务队列。

事件循环 (Event Loop)

事件循环是一个不断运行的循环,它负责轮询任务队列(宏任务队列和微任务队列)并执行任务。其工作流程如下:

  1. 执行同步任务: 执行当前脚本中所有同步代码。
  2. 检查微任务队列: 如果有微任务,则将它们从队列中取出并执行。
  3. 检查宏任务队列: 如果有宏任务,则将它从队列中取出并执行。
  4. 渲染页面: 更新 UI,反映任务执行期间产生的任何更改。
  5. 回到步骤 1 ,继续循环。

执行机制

宏任务和微任务的执行顺序遵循以下规则:

  • 同步任务总是先于异步任务执行。
  • 微任务总是先于宏任务执行,即使它们是在同一个事件循环周期内加入队列的。
  • 如果一个任务在执行过程中产生新的微任务,则该微任务会在当前宏任务执行完毕后立即执行。

示例

以下示例展示了宏任务和微任务的执行顺序:

console.log('同步 1'); // 同步任务

Promise.resolve().then(() => {
  console.log('微任务 1'); // 微任务
});

setTimeout(() => {
  console.log('宏任务 1'); // 宏任务
}, 0);

console.log('同步 2'); // 同步任务

process.nextTick(() => {
  console.log('微任务 2'); // 微任务
});

输出结果:

同步 1
同步 2
微任务 1
微任务 2
宏任务 1

总结

宏任务、微任务和事件循环机制是理解 JavaScript 执行机制的关键概念。通过了解这些概念,开发者可以编写更高效、响应更快的应用程序。