JavaScript执行顺序:同步任务 > 微任务 > 宏任务
宏任务与微任务的区别:
- 微任务:在每个宏任务执行结束后立即执行,优先级高于宏任务
- 宏任务:由宿主环境(如浏览器)发起的任务,包括事件回调、定时器等
常见的宏任务与微任务:
| 任务类型 | 具体API |
|---|---|
| 宏任务 | setTimeout、setInterval、I/O操作 |
| 微任务 | Promise.then、MutationObserver |
| ⚠️渲染任务 | requestAnimationFrame(在浏览器渲染前执行,不属于宏任务/微任务) |
练习
一个常见的执行顺序题目,输出打印结果顺序:
console.log('start');
setTimeout(() => {
console.log('setTimeout 1');
Promise.resolve().then(() => {
console.log('Promise 2');
setTimeout(() => {
console.log('setTimeout 3');
}, 0);
});
}, 0);
Promise.resolve().then(() => {
console.log('Promise 1');
setTimeout(() => {
console.log('setTimeout 2')
}, 0);
});
console.log('end');
-
同步代码执行:
- 输出
start - 将
setTimeout1加入宏任务队列 - 将
Promise1.then加入微任务队列 - 输出
end
- 输出
-
检查微任务队列:
- 执行
Promise1.then→ 输出Promise1 - 将
setTimeout2加入宏任务队列 - 微任务队列清空
- 执行
-
取出第一个宏任务(
setTimeout1):- 输出
setTimeout1 - 将
Promise2.then加入微任务队列
- 输出
-
再次检查微任务队列:
- 执行
Promise2.then→ 输出Promise2 - 将
setTimeout3加入宏任务队列
- 执行
-
继续执行宏任务队列:
- 执行
setTimeout2→ 输出setTimeout2 - 执行
setTimeout3→ 输出setTimeout3
- 执行
打印顺序为:
start
end
Promise 1
setTimeout 1
Promise 2
setTimeout 2
setTimeout 3