定义
JavaScript从诞生以来就是个单线程的语言,每次只能执行一个任务,其他任务排队等候,那排队等候的机制是什么呢?这个机制其实就是event loop(事件循环)
在event loop中有三个必要的概念
- 执行栈
也就是调用栈,所有的JavaScript代码执行的地方 - 微任务
Promise成功或失败回调,Object.observe…… - 宏任务
setTimeout,setInterval回调
event loop执行顺序
1.浏览器在加载了一段js代码后,会逐行在执行栈中执行,遇到微任务将其取出暂存在微任务队列中,遇到宏任务将其取出暂存在宏任务队列中
2.步骤1执行完毕后,会查看微任务队列中是否有暂存,有则依次取出放回到执行栈中执行
3.步骤2执行完毕后,发现微任务队列已经清空,则查看宏任务队列中是否有暂存,有则取出第一条放回到执行栈中执行
4.步骤3中执行完一条宏任务后,会再次查看微任务队列是否有暂存,有则执行步骤2->3
示例代码
console.log(1);
setTimeout(() => {
console.log(2);
new Promise((resolve)=>{
console.log(8)
resolve()
}).then(() => {
console.log(3)
});
});
new Promise((resolve, reject) => {
console.log(4)
resolve(5)
}).then((data) => {
console.log(data);
})
setTimeout(() => {
console.log(6);
})
console.log(7);
执行结果:
1
4
7
5
2
8
3
6
分析:
1.加载这段js代码,在执行栈中逐行执行
第一块:console.log(1) 输出1
第二块:发现setTimeout,将其回调存入宏任务队列
第三块:发现Promise,执行Promise回调函数,发现console.log(4)输出4
,发现resolve,将成功回调存入微任务队列
第四块:发现setTimeout,将其回调存入宏任务队列
第五块:console.log(7)输出7
2.代码块逐行执行完毕,执行栈清空,检查微任务队列,将其取出放入执行栈执行
第三块的then回调执行,console.log(data)输出5
3.微任务队列清空,检查宏任务队列,取出第一条宏任务
第二块的setTimeout回调执行
console.log(2) 输出2
发现Promise,执行Promise的回调主体,console.log(8)输出8
,发现resolve,将成功then回调存入微任务队列
本次宏任务执行完毕
4.检查微任务队列,有上一步宏任务中发现的Promise成功回调微任务,将其取出放入执行栈执行
console.log(3)输出3
5.微任务队列清空,检查宏任务队列,取出第二条宏任务
第四块的setTimeout回调执行
console.log(6)输出6
6.检查微任务队列,为空。继续检查宏任务队列,为空,代码执行完毕