目录
在JavaScript中,理解 微任务(Microtasks) 和 宏任务(Macrotasks) 是理解异步编程和事件循环机制的核心。微任务和宏任务是事件队列的两类任务,它们的执行顺序和优先级直接影响着JavaScript代码的执行流。本文将通过详细示例来介绍这两个概念,帮助你更好地理解JavaScript的异步机制。
什么是宏任务和微任务?
- 宏任务(Macrotasks):
- 宏任务是 JavaScript 中的主要任务,它包括常见的任务类型,如:
setTimeout
、setInterval
、DOM事件(click、keydown等)、AJAX请求回调等。 - 宏任务会被放入 宏任务队列,在主线程空闲时执行。
- 宏任务是 JavaScript 中的主要任务,它包括常见的任务类型,如:
- 微任务(Microtasks):
- 微任务是比宏任务更细粒度的任务,它们会在当前任务执行完后,立即执行。
- 常见的微任务包括:
Promise
的回调函数、MutationObserver
等。 - 微任务会被放入 微任务队列,并且微任务队列的任务会在当前宏任务执行完成之后、下一个宏任务开始之前执行。
事件循环机制:
- 事件循环 是 JavaScript 引擎中调度异步任务的机制。它通过不断地检查任务队列中的任务,决定哪个任务应该被执行。简单来说,事件循环不断地从任务队列中取出任务并执行,按照宏任务和微任务的顺序。
- 事件循环的执行顺序:
- 执行当前宏任务。
- 执行所有微任务(如果有)。
- 执行下一个宏任务。
示例代码:
目标:
我们将通过一个简单的示例,来演示宏任务和微任务的执行顺序。
代码说明:
-
HTML部分:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>微任务与宏任务示例</title> </head> <body> <h1>微任务与宏任务示例</h1> </body> </html>
-
JavaScript部分:
<script> console.log("Script Start"); // 宏任务 1: setTimeout (异步操作) setTimeout(() => { console.log("宏任务 1"); }, 0); // 微任务 1: Promise.then (异步操作) Promise.resolve().then(() => { console.log("微任务 1"); }); // 宏任务 2: setTimeout (异步操作) setTimeout(() => { console.log("宏任务 2"); }, 0); // 微任务 2: Promise.then (异步操作) Promise.resolve().then(() => { console.log("微任务 2"); }); console.log("Script End"); </script>
代码解析:
-
同步代码:
- 第一个
console.log("Script Start")
会同步执行,输出Script Start
。 - 第二个
console.log("Script End")
也会同步执行,输出Script End
。
- 第一个
-
宏任务:
- 第一个
setTimeout
被添加到 宏任务队列,它会在当前任务执行完毕后执行,输出宏任务 1
。 - 第二个
setTimeout
也被添加到 宏任务队列,并将在事件循环中等待执行,输出宏任务 2
。
- 第一个
-
微任务:
- 第一个
Promise.resolve().then()
被添加到 微任务队列。在当前宏任务执行后,微任务会立即执行,输出微任务 1
。 - 第二个
Promise.resolve().then()
也被添加到 微任务队列,会在第一个微任务执行后执行,输出微任务 2
。
- 第一个
执行顺序:
JavaScript 执行顺序如下:
-
同步代码:
console.log("Script Start")
:输出Script Start
。console.log("Script End")
:输出Script End
。
-
微任务:
- 微任务队列会在当前宏任务执行后、下一个宏任务执行前执行。
Promise.resolve().then(() => { console.log("微任务 1"); })
:输出微任务 1
。- 第二个微任务:
Promise.resolve().then(() => { console.log("微任务 2"); })
:输出微任务 2
。
-
宏任务:
- 第一个宏任务
setTimeout(() => { console.log("宏任务 1"); }, 0)
被执行,输出宏任务 1
。 - 第二个宏任务
setTimeout(() => { console.log("宏任务 2"); }, 0)
被执行,输出宏任务 2
。
- 第一个宏任务
执行结果:
Script Start
Script End
微任务 1
微任务 2
宏任务 1
宏任务 2
总结:
- 同步代码:先执行,立即输出。
- 微任务:微任务队列中的任务在当前任务完成后、下一个宏任务前执行,优先级高于宏任务。
- 宏任务:宏任务队列中的任务在微任务执行完后才执行,优先级低于微任务。
理解微任务和宏任务的区别及其执行顺序,对于正确理解 JavaScript 的异步机制至关重要。微任务通常用于处理更细粒度的任务,而宏任务则是用于处理较大的异步操作。通过事件循环机制,JavaScript 确保了任务的有序执行。
文件名:
index.html
script.js
附加说明:
- 以上示例通过
setTimeout
和Promise
来展示宏任务和微任务的执行顺序。你可以根据需要,替换成其他的异步操作来进一步实验和理解。