返回

揭开JS事件循环的神秘面纱:从宏任务到微任务

前端

在现代Web开发中,JavaScript (JS)已成为不可或缺的利器。为了处理复杂的用户交互和异步操作,JS引入了一套独特的事件循环机制,它包含了宏任务和微任务的概念。理解这些概念对于掌握JS异步编程至关重要。

1. 事件循环の概要

JS事件循环是一个负责协调和执行各种任务的机制,它允许JS代码在单线程环境中模拟多线程行为。事件循环不断地从一个称为"事件队列"的数据结构中提取任务,并将其执行。

2. 宏任务和微任务

在JS事件循环中,任务分为宏任务和微任务。宏任务是指那些需要较长时间才能完成的任务,例如:

  • 脚本执行:这是JS代码的主体,包括函数调用、变量声明等。
  • setTimeout():这是一个内置函数,允许在指定的时间延迟后执行一个函数。
  • setInterval():这是一个内置函数,允许在指定的间隔时间内重复执行一个函数。

微任务是指那些需要在宏任务执行之前执行的任务,例如:

  • Promise:这是一个内置对象,用于处理异步操作。
  • MutationObserver:这是一个内置对象,用于监听DOM元素的变化。
  • requestAnimationFrame():这是一个内置函数,允许在浏览器下一次重新绘制之前执行一个函数。

3. 事件循环的执行过程

JS事件循环的执行过程遵循以下步骤:

  1. 执行同步任务 :首先,事件循环会执行同步任务,即那些不需要等待任何异步操作的任务。
  2. 将微任务添加到微任务队列 :在执行同步任务的同时,如果遇到微任务,则将其添加到微任务队列中。
  3. 执行宏任务 :当同步任务执行完毕后,事件循环会从宏任务队列中取出一个宏任务并执行。
  4. 执行微任务 :在执行宏任务期间,如果遇到微任务,则将其添加到微任务队列中。
  5. 重复步骤2至4 :事件循环会不断地重复步骤2至4,直到宏任务队列和微任务队列都为空。

4. 宏任务和微任务的示例

为了更好地理解宏任务和微任务,让我们来看一些示例:

宏任务示例

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

// 宏任务:setInterval()
setInterval(() => {
  console.log("宏任务2");
}, 1000);

// 宏任务:脚本执行
console.log("宏任务3");

微任务示例

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

// 微任务:MutationObserver
const observer = new MutationObserver(() => {
  console.log("微任务2");
});

observer.observe(document.body, {
  attributes: true
});

// 微任务:requestAnimationFrame()
requestAnimationFrame(() => {
  console.log("微任务3");
});

5. 结论

宏任务和微任务是JS事件循环的重要组成部分,它们共同协作以处理同步任务和异步任务。理解这些概念对于编写高效的JS代码至关重要。