在 Event Loop 和宏/微任务中掌控 JS 世界
2023-09-22 17:13:32
在 JavaScript 世界中,Event Loop(事件循环)、宏任务(Macrotasks)和微任务(Microtasks)是三个重要的概念。理解它们对于成为一名优秀的 JavaScript 开发人员至关重要。在本文中,我们将深入探讨这些概念,并通过生动的例子来帮助您理解它们。
一、什么是事件循环?
事件循环是 JavaScript 引擎用来处理任务的机制。它是一个无限循环,不断检查是否有要执行的任务,并按照一定的顺序执行它们。事件循环的工作方式如下:
- 当 JavaScript 引擎收到一个任务时,它会将其放入一个队列中。
- 事件循环不断从队列中取出任务并执行它们。
- 当一个任务执行完成后,它会从队列中删除。
- 事件循环不断重复步骤 2 和 3,直到队列中没有任务需要执行为止。
二、什么是宏任务?
宏任务是 JavaScript 引擎可以执行的任何任务。宏任务包括以下几种类型:
- 脚本代码:这是您在 JavaScript 文件中编写的代码。
- setTimeout() 和 setInterval() 函数调用的回调函数。
- DOM 事件处理程序(例如,click、mouseover 等)。
宏任务按照它们被添加到队列中的顺序执行。也就是说,先添加的宏任务会先执行。
三、什么是微任务?
微任务是 JavaScript 引擎可以执行的特殊类型的任务。微任务包括以下几种类型:
- Promise 的 then() 方法的回调函数。
- MutationObserver 的回调函数。
- requestAnimationFrame() 的回调函数。
微任务按照它们被添加到队列中的顺序执行,但是它们会在宏任务之前执行。也就是说,如果队列中同时存在宏任务和微任务,那么微任务会先执行。
四、事件循环、宏任务和微任务的示例
为了更好地理解事件循环、宏任务和微任务,我们来看一个示例:
console.log('start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('promise');
});
console.log('end');
当这段代码执行时,会发生以下情况:
- JavaScript 引擎收到代码并将其放入队列中。
- 事件循环从队列中取出第一个任务(console.log('start')) 并执行它。
- 事件循环从队列中取出第二个任务(setTimeout() 的回调函数)并执行它。
- setTimeout() 的回调函数将 "setTimeout" 输出到控制台。
- 事件循环从队列中取出第三个任务(Promise 的 then() 方法的回调函数)并执行它。
- Promise 的 then() 方法的回调函数将 "promise" 输出到控制台。
- 事件循环从队列中取出第四个任务(console.log('end')) 并执行它。
在这个示例中,宏任务是 setTimeout() 的回调函数和 console.log('end'),而微任务是 Promise 的 then() 方法的回调函数。微任务在宏任务之前执行,因此 "promise" 会在 "setTimeout" 之前输出到控制台。
五、总结
事件循环、宏任务和微任务是 JavaScript 中三个重要的概念。理解它们对于成为一名优秀的 JavaScript 开发人员至关重要。通过本文,您已经掌握了这些概念的基础知识。现在,您可以在实际开发中应用它们,并编写出更加高效、健壮的 JavaScript 代码。