返回

在 Event Loop 和宏/微任务中掌控 JS 世界

前端

在 JavaScript 世界中,Event Loop(事件循环)、宏任务(Macrotasks)和微任务(Microtasks)是三个重要的概念。理解它们对于成为一名优秀的 JavaScript 开发人员至关重要。在本文中,我们将深入探讨这些概念,并通过生动的例子来帮助您理解它们。

一、什么是事件循环?

事件循环是 JavaScript 引擎用来处理任务的机制。它是一个无限循环,不断检查是否有要执行的任务,并按照一定的顺序执行它们。事件循环的工作方式如下:

  1. 当 JavaScript 引擎收到一个任务时,它会将其放入一个队列中。
  2. 事件循环不断从队列中取出任务并执行它们。
  3. 当一个任务执行完成后,它会从队列中删除。
  4. 事件循环不断重复步骤 2 和 3,直到队列中没有任务需要执行为止。

二、什么是宏任务?

宏任务是 JavaScript 引擎可以执行的任何任务。宏任务包括以下几种类型:

  1. 脚本代码:这是您在 JavaScript 文件中编写的代码。
  2. setTimeout() 和 setInterval() 函数调用的回调函数。
  3. DOM 事件处理程序(例如,click、mouseover 等)。

宏任务按照它们被添加到队列中的顺序执行。也就是说,先添加的宏任务会先执行。

三、什么是微任务?

微任务是 JavaScript 引擎可以执行的特殊类型的任务。微任务包括以下几种类型:

  1. Promise 的 then() 方法的回调函数。
  2. MutationObserver 的回调函数。
  3. requestAnimationFrame() 的回调函数。

微任务按照它们被添加到队列中的顺序执行,但是它们会在宏任务之前执行。也就是说,如果队列中同时存在宏任务和微任务,那么微任务会先执行。

四、事件循环、宏任务和微任务的示例

为了更好地理解事件循环、宏任务和微任务,我们来看一个示例:

console.log('start');

setTimeout(() => {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(() => {
  console.log('promise');
});

console.log('end');

当这段代码执行时,会发生以下情况:

  1. JavaScript 引擎收到代码并将其放入队列中。
  2. 事件循环从队列中取出第一个任务(console.log('start')) 并执行它。
  3. 事件循环从队列中取出第二个任务(setTimeout() 的回调函数)并执行它。
  4. setTimeout() 的回调函数将 "setTimeout" 输出到控制台。
  5. 事件循环从队列中取出第三个任务(Promise 的 then() 方法的回调函数)并执行它。
  6. Promise 的 then() 方法的回调函数将 "promise" 输出到控制台。
  7. 事件循环从队列中取出第四个任务(console.log('end')) 并执行它。

在这个示例中,宏任务是 setTimeout() 的回调函数和 console.log('end'),而微任务是 Promise 的 then() 方法的回调函数。微任务在宏任务之前执行,因此 "promise" 会在 "setTimeout" 之前输出到控制台。

五、总结

事件循环、宏任务和微任务是 JavaScript 中三个重要的概念。理解它们对于成为一名优秀的 JavaScript 开发人员至关重要。通过本文,您已经掌握了这些概念的基础知识。现在,您可以在实际开发中应用它们,并编写出更加高效、健壮的 JavaScript 代码。