一、介绍
JavaScript 是单线程的,事件循环就是它用来“协调异步任务执行”的机制。这里还要介绍一下栈(Stack)和队列(Queue)。
1.Call Stack,调用堆栈

JS的Call Stack是一种经典的栈结构,它的特点是后进先出(last in first out,LIFO),下面例子可以解释:
function a() {
b();
}
function b() {
c();
}
function c() {
console.log("Hello");
}
a();
调用顺序:
Call Stack:
→ c
→ b
→ a
2.Task Queue,任务队列
任务队列(Task Queue)是指在事件循环中等待执行的异步回调任务的集合,包含宏任务队列(Macrotask Queue)和微任务队列(Microtask Queue)。这些任务会在主线程空闲(同步代码执行完)后被依次执行,确保 JavaScript 单线程环境中的异步操作可以“有序排队”。
3.事件循环的执行流程
- 执行主线程代码(立即执行同步任务)
- 检查异步任务队列(宏任务队列 / 微任务队列)
- 取出任务执行
- 当前宏任务执行完之后立即执行 微任务
- 下一轮事件循环中执行 宏任务
- 重复执行这个循环
二、常见任务类型
任务类型 | 示例 | 队列类型 |
同步任务 | 普通代码 | 主线程直接执行 |
微任务 (Microtask) | Promise.then Promise.catch Promise.finally queueMicrotask | 微任务队列(优先),在当前同步任务之后执行 |
宏任务 (Macrotask) | setTimeout setInterval setImmediate requestAnimationFrame DOM 事件(click, input, keydown, load, scroll 等用户交互事件) | 宏任务队列,执行一次循环之后,排在下一个宏任务中执行 |
三、案例题目
console.log("start")
setTimeout ( ()=>{
console.log ('timer1')
new Promise (function (resolve){
console.log(" promise start ")
resolve ();
}).then (function () {
console. log('promise1')
// 注意:如果这里还有一个setimeout,那么输出将在promise2之后
})
},0)
setTimeout (() =>{
console.log( 'timer2')
Promise.resolve( ).then(function() {
console. log('promise2')
})
},0)
console. log("end")
结果:
start // 同步
end // 同步
timer1 // 第一个宏任务中的同步任务
promise start // 第一个宏任务中的同步任务 new Promise(...)
promise1 // 第一个宏任务中的微任务
timer2 // 第二个宏任务的同步任务
promise2 // 第二个宏任务的微任务