js中的宏任务和微任务
文章类型:Javascript
发布者:hp
发布时间:2024-12-03
端开发中,尤其是在面试中,我们经常听到宏任务(Macro Task)和微任务(Micro Task)这两个概念。这两个概念是在 JavaScript 中任务调度过程中的重要组成部分,那么,他们是什么呢?
1:定义:每次执行栈执行的代码当做是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行),每一个宏任务会从头到尾执行完毕,不会执行其他,说白了就是JS主线程执行的任务
2:常用场景:
(1)浏览器事件(如 click、mouseover 等)
(2)定时器任务(如 setTimeout 和 setInterval)
(3)页面渲染(如 回流或重绘)
(4)事件回调(如 I/O、点击事件等)
(5)网络请求 (如 XMLHttpRequest 和 fetch 等)
3:作用:宏任务通常独立于当前任务,并按顺序排队执行
4:代码:
// 事件监听器创建宏任务
const button = document.querySelector("button");
button.addEventListener("click", () => {
console.log("Button clicked");
});
console.log("Waiting for button click...");
1:定义:当前 宏任务执行后立即执行的任务,当 宏任务执行完,会在渲染前,将执行期间所产生的所有 微任务都执行完
2:常用场景
(1)Promise 的回调函数
(2)Async/Await 函数
(3)MutationObserver 的回调函数
(4)process.nextTick(Node.js 环境下)
3:作用:微任务是 JavaScript 中处理异步操作的一种机制,它通过及时响应并在当前任务结束后立即执行,有助于编写更高效和灵活的异步代码
4:代码:
console.log("1");
setTimeout(() => {
console.log("2");
Promise.resolve().then(() => console.log("3"));
});
Promise.resolve().then(() => console.log("4"));
console.log("5");
1:宏任务是由 JavaScript 引擎在执行栈(执行同步任务)和任务队列中的任务之间切换时执行的。按照宏任务队列的顺序执行
2:微任务是在宏任务执行结束,下一个宏任务开始之前执行的任务。在当前宏任务中执行完后立即执行,并按照微任务队列的顺序执行
1:宏任务当主线程执行完当前宏任务后,会检查是否存在微任务,如果存在,则会执行所有微任务,然后选择下一个宏任务执行,使用先进先出的调度机制,即它们按照任务的顺序排列,并按顺序执行
2:微任务队列中存在微任务时,会依次执行微任务,直到微任务队列为空,微任务则使用一个任务队列(microtask queue)进行调度,当宏任务执行完毕后,会立即将所有的微任务添加到任务队列中,并按照先进先出的顺序依次执行
1:执行一个 宏任务(栈中没有就从 事件队列中获取),执行过程中如果遇到 微任务,就将它添加到 微任务的任务队列中
2:宏任务执行完毕后,立即执行当前 微任务队列中的所有 微任务(依次执行)
3:当前 宏任务执行完毕,开始检查渲染,然后 GUI线程接管渲染
4:渲染完毕后, JS线程继续接管,开始下一个 宏任务(从事件队列中获取)
5:微任务优先级高于宏任务,因此在同一轮事件循环中,微任务会优先执行
(一)事件循环机制(Event Loop)
1:定义:是 JavaScript 引擎用来处理异步任务的一种机制。它负责维护一个任务队列,并按照一定的规则循环执行任务队列中的任务
2:图解:
3:执行流程:
执行同步任务(从上到下逐行执行)->遇到异步任务(添加到微任务队列中)->执行宏任务(当同步任务执行完成,执行宏任务队列任务,如遇到嵌套微任务,则添加到微任务队列)->执行微任务(执行完一个宏任务后,立即执行微任务队列中的所有微任务)->循环执行,直到任务队列为空