EventLoop 事件循环 宏任务队列与微任务队列
EventLoop 宏任务和微任务
js中用来存储执行回调函数的队列包括2个不同的特定的队列,即宏队列和微队列
宏任务包括定时器、ajax异步回调、事件回调
微任务包括promise,mutation
需要明确的是,所有函数,不论宏任务队列微任务队列或者是同步执行的函数,最终都是要放到在栈里面调用执行的
执行顺序:
- js引擎首先必须先执行所有的初始化同步任务代码
- 每次准备去除第一个宏任务前,都要将所有的微任务一个一个取出来执行
- 对于then的链式调用,只有当前then的上一个then执行完毕之后,当前then才会被加入微任务队列(而不是立即执行,仅仅只是加入队列)
栈里面的同步执行函数,然后是微队列,然后是宏队列
假如队列里有多个任务,那么队列里的任务按加入的顺序依次执行
测试用例
0
setTimeout(() => {
console.log('宏任务 settimeout')
}, 0)
Promise.resolve(1).then(
value => {
console.log('微任务 promise')
}
)
let a = function(){
console.log('synchronize fn')
}
a()
// 打印顺序
/*
synchronize fn
微队列 promise
宏队列 settimeout
*/
1
setTimeout(()=>{
console.log(1)
})
Promise.resolve(2).then(
value => console.log(value)
)
Promise.resolve(3).then(
value => console.log(value)
)
console.log(4)
/*
打印顺序
4
2
3
1
*/
2
setTimeout(()=>{
console.log(1)
},0)
new Promise((resolve)=>{
//执行器函数,同步的,首先打印
console.log(2)
resolve()
})
.then(
()=>{
console.log(3)
}
)
.then(()=>{
console.log(4)
})
console.log(5)
/*
打印顺序
2
5
3
4
1
*/
3
/*
1 7 2 3 8 4 6 5 0
微队列:[4 6 5]
宏队列:[0]
*/
setTimeout(() => {
console.log("O")
}, 0)
new Promise((resolve, reject) => {
console.log("1")
resolve()
})
.then(() => {
//微任务1
console.log("2")
new Promise((resolve, reject) => {
console.log("3")
resolve()
}).then(() => {
//微任务3,此时3在队列里,3没有执行,5不会被放入队列,3执行了5才会放入队列
console.log("4")
}).then(() => {
//微任务5
console.log("5")
})
}).then(() => {
//微任务4
console.log("6")
})
new Promise((resolve,reject)=>{
console.log('7')
resolve()
}).then(()=>{
//微任务2
console.log('8')
})
4
/*
1 4 2 3 5
*/
document.addEventListener("chilema", chileMaHandler);
console.log(1);
function fn1() {
fn2();
console.log(2);
}
function fn2() {
console.log(3);
}
console.log(4);
function chileMaHandler() {
fn1();
console.log(5);
}
document.dispatchEvent(new Event("chilema"));
/*
1 4 2 3 5
6 12 16 15 7 8 9 10 11 13 14
微队列:[]
宏队列:[14]
*/
new Promise(function (resolve, reject) {
console.log(6);
setTimeout(function () {
console.log(7);
resolve();
}, 0);
}).then(function () {
console.log(8);
}).then(function () {
console.log(9);
})
setTimeout(function () {
console.log(10);
Promise.resolve().then(function () {
console.log(11);
})
}, 0);
new Promise(function (resolve, reject) {
console.log(12);
setTimeout(function () {
console.log(13);
}, 0);
resolve();
}).then(function () {
setTimeout(function () {
console.log(14);
});
Promise.resolve().then(function () {
console.log(15);
});
console.log(16);
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!