为什么要设计微任务?
微任务的设计目的
微任务(Microtask)的设计主要是为了解决高优先级异步任务的执行时机问题。如果没有微任务机制:
-
只有宏任务时的问题:
- 所有异步任务(包括 Promise 回调)都会进入宏任务队列
- 这些任务必须等待当前宏任务完全执行完毕,浏览器渲染,然后才能执行下一个宏任务
- 这会导致 UI 更新不够及时,影响用户体验
-
微任务的优势:
- 允许某些高优先级任务(如 Promise 回调)在当前宏任务执行完毕后、渲染前执行
- 确保 UI 更新前所有相关的数据状态都已准备就绪
没有微任务会怎样?
如果只有宏任务,以下场景会出问题:
// 假设没有微任务,Promise.then也进入宏任务队列
button.addEventListener("click", () => {
// 同步修改DOM
status.textContent = "加载中...";
// 假设这是宏任务
fetchData().then((data) => {
status.textContent = `加载完成: ${data}`;
});
// 如果没有微任务,这里会立即渲染"加载中..."吗?
// 实际 上不会,因为事件处理本身就是一个宏任务
});
微任务如何工作
-
执行时机:
- 在当前宏任务执行完毕后
- 在浏览器渲染之前
- 执行所有已排队的微任务
-
实际流程:
开始宏任务
├─ 执行同步代码
├─ 遇到微任务,加入微任务队列
└─ 宏任务结束
↓
清空微任务队列
↓
渲染(如果需要)
↓
下一个宏任务
结论
- 没有微任务:所有异步任务都是宏任务,必须等待浏览器渲染后才能执行,导致 UI 更新不够及时
- 有微任务:可以在渲染前执行高优先级任务,确保 UI 更新时数据已准备就绪
微任务机制是 JavaScript 事件循环中非常重要的设计,它使得开发者能够更精确地控制异步代码的执行时机,特别是在需要快速响应用户交互或更新 UI 时。