个人理解总结
调用栈(同步代码) → 微任务队列 → 宏任务队列
1. 事件循环的执行顺序示例
假设有以下代码:
console.log("Start");
setTimeout(() => {
console.log("Timeout callback");
}, 0);
Promise.resolve().then(() => {
console.log("Promise callback");
});
console.log("End");
执行顺序:
- 同步代码
console.log("Start")
和console.log("End")
优先执行。 setTimeout
的回调被推入 宏任务队列。Promise.then
的回调被推入 微任务队列。- 当同步代码完成后,事件循环先执行微任务队列中的
Promise.then
,输出"Promise callback"
。 - 微任务队列清空后,事件循环执行宏任务队列中的
setTimeout
,输出"Timeout callback"
。
输出顺序为:
Start
End
Promise callback
Timeout callback
2. 事件循环机制
JavaScript是单线程,就是每次只能执行一个任务。为了实现异步任务执行就创造了 事件循环和任务队列。事件循环的工作方式如下 1.js引擎会优先执行同步代码 2.遇到 setTimeout Promise async await后 js引擎会把它们交给浏览器或者nodejs 继续执行同步代码 3.一旦异步任务完成 会将它们回调任务 加入队列 4.同步代码执行完毕后会从 微任务队列和宏任务队列取出任务按照优先级进行执行
3. 执行优先级:微任务 vs 宏任务
JavaScript 中的任务分为 微任务(Microtask) 和 宏任务(Macrotask) 。微任务的优先级高于宏任务,意味着每次事件循环时,微任务队列中的任务会优先被执行。
微任务(Microtask)
- 常见的微任务:
Promise.then
、async/await
、queueMicrotask
、MutationObserver
- 执行时机:当前同步代码和调用栈中的任务完成后立即执行,但在下一个宏任务之前。
- 特点:事件循环每次检查任务队列时会先清空微任务队列,再执行宏任务队列中的下一个任务。
宏任务(Macrotask)
- 常见的宏任务:
setTimeout
、setInterval
、setImmediate
(Node.js)、I/O
操作、UI rendering
- 执行时机:微任务队列中的所有任务清空后,才会执行宏任务队列中的第一个任务。
- 特点:宏任务队列中的任务按顺序执行,每执行一个宏任务,事件循环会再次检查微任务队列并优先清空微任务。
4. 微任务和宏任务嵌套 你中有我 我中有你 执行顺序如何呢?
案例1
console.log("Start");
setTimeout(() => {
console.log("Timeout callback");
Promise.resolve().then(() => {
console.log("Promise2 callback");
});
}, 0);
Promise.resolve().then(() => {
console.log("Promise callback");
setTimeout(() => {
console.log("Timeout2 callback");
}, 0);
});
console.log("End");
执行结果是
Start
End
Promise callback
Timeout callback
Promise2 callback
Timeout2 callback
案例2 如果微任务的延迟时间改长结果呢
console.log("Start");
setTimeout(() => {
console.log("Timeout callback");
Promise.resolve().then(() => {
console.log("Promise2 callback");
});
}, 0);
Promise.resolve().then(() => {
console.log("Promise callback");
setTimeout(() => {
console.log("Timeout2 callback");
}, 2000);
});
console.log("End");
结果 Timeout2 callback延迟了2s打印
Start
End
Promise callback
Timeout callback
Promise2 callback
Timeout2 callback