常见的宏任务来源:
-
setTimeout
/setInterval
(定时器回调) -
I/O 操作
(如文件读写、网络请求完成后的回调) -
DOM 事件回调
(如click
、scroll
、resize
) -
requestAnimationFrame(UI渲染)
(浏览器渲染前执行,通常归类为宏任务) -
主线程代码(
<script>
标签中的同步代码)
(整体作为一个宏任务)
常见的微任务来源:
-
Promise.then()
/Promise.catch()
/Promise.finally()
(Promise 的异步回调) -
MutationObserver
(监听 DOM 变化的回调) -
Object.obverse(废弃接口,建议使用Proxy对象替代)
-
process.nextTick
(Node.js 独有)
(优先级高于 Promise)
事件循环流程:
-
执行一个 宏任务(如
script
主代码)。 -
执行所有 微任务(清空微任务队列)。
-
浏览器可能执行 渲染(UI 更新)。
-
取下一个宏任务,重复循环。
执行顺序:同步代码 → 微任务 → 渲染 → 宏任务。
课外疑问一:所有微任务执行完之后,浏览器可能进行渲染(ui更新),但是MutationObserver又是监视DOM变化的回调的作用。问题就是,我微任务MutationObserver已经执行完了,浏览器才进行渲染,那MutationObserver监听的dom还没渲染出来吗?
解答:
1,MutationObserver 监听的是内存中的 DOM 变化,与浏览器是否完成渲染无关。
2,渲染是独立的后置步骤,由浏览器异步调度。
3,若需依赖渲染后的布局信息,应在 requestAnimationFrame
或 setTimeout
中处理。
1. 同步代码修改 DOM → DOM 内存更新 2. MutationObserver 回调加入微任务队列 3. 同步代码执行完毕 4. 执行所有微任务(包括 MutationObserver 回调) 5. (可选)浏览器渲染(样式计算 → 布局 → 绘制) 6. 下一个事件循环