js事件循环
2026-09-07 11:11:32
JS 为单线程语言,靠事件循环调度任务。 事件循环(Event Loop)的优先级大致为: 同步任务 → 微任务队列 → 宏任务队列 但是实际执行还要结合 调用栈(Call Stack)、任务队列(Task Queue)、浏览器渲染 来理解。
常见微任务
| API | 类型 |
|---|---|
| Promise.then | 微任务 |
| queueMicrotask | 微任务 |
| MutationObserver | 微任务 |
| async/await | 微任务 |
常见宏任务
| API | 类型 |
|---|---|
| setTimeout | 宏任务 |
| setInterval | 宏任务 |
| setImmediate(Node) | 宏任务 |
| I/O | 宏任务 |
| UI事件 | 宏任务 |
微任务为什么优先?
因为微任务用于处理: Promise状态变化 async结果 DOM变化监听
它要求:当前任务完成后,尽快执行,不应该等待下一轮事件循环。
宏任务中的微任务,微任务会一直清空
执行一个宏任务后,会把产生的所有微任务全部执行完
setTimeout(()=>{
console.log(1)
Promise.resolve()
.then(()=>{
console.log(2)
})
},0)
setTimeout(()=>{
console.log(3)
},0)
//输出:1 -> 2 -> 3
微任务中的微任务
Promise.resolve()
.then(()=>{
console.log(1)
Promise.resolve()
.then(()=>{
console.log(2)
})
})
Promise.resolve()
.then(()=>{
console.log(3)
})
//输出:1 -> 3 -> 2
微任务中的宏任务
console.log('1'); // 同步
setTimeout(() => console.log('2')); // 宏任务
Promise.resolve().then(() => {
console.log('3'); // 微任务
setTimeout(() => console.log('4'));// 宏任务
});
// 输出:1 → 3 → 2 → 4
Node.js事件循环优先级(特殊)
process.nextTick ↓ Promise微任务 ↓ timer(setTimeout) ↓ I/O ↓ setImmediate
setTimeout(()=>{
console.log("timeout")
})
setImmediate(()=>{
console.log("immediate")
})
process.nextTick(()=>{
console.log("nextTick")
})
Promise.resolve()
.then(()=>{
console.log("promise")
})
//输出:nextTick-> promise -> timeout -> immediate
Vue中的事件循环
nextTick(()=>{
console.log("update")
})
底层为:Promise.resolve().then(flushJobs)
修改响应式数据-> trigger -> scheduler -> queueJob -> Promise.then -> 微任务执行组件更新