本文受https://segmentfault.com/a/1190000015057278文章启发。
不过感觉作者写得比较冗余,且有些东西还是没有讲明白。于是我尝试用更进阶的代码并配上更简洁的注释来讲明白这些事情。
1. 事件循环
js在执行的过程中是单线程的,所以采用了事件循环机制。也就是说,从上往下执行。执行完毕 => 判断是否
微任务
=> 判断是否有宏任务
2.回调队列
宏任务目前就简单的理解为setTimeout就ok了。而微任务就理解为回调函数的回调队列,这里包含await promise callback。
某种意义上来说, await 是 对 promise 的封装 , 而 promise 又是对 callback 的封装。所以,其实是一回事儿。
即使看不懂上边的两点也无所谓,下面进入重点,废话少说,直接贴代码。
async function async1(){
console.log('async1 start')
console.log('async1 print',await async2())
console.log('async1 end')
}
async function async2(){
console.log('async2 start')
console.log('async2 print',await async3())
console.log('async2 end')
}
async function async3(){
console.log('async3')
}
console.log('进程 start')
setTimeout(function(){
console.log('setTimeout1')
},0)
setTimeout(function(){
console.log('setTimeout2')
},0)
async1();
new Promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise1 resolve')
})
new Promise(function(resolve){
console.log('promise2')
resolve();
}).then(function(){
console.log('promise2 resolve')
})
console.log('进程 end')
看起来其实挺绕的,如果你看了开篇那篇文章,且看不明白,那你就看我的吧。虽然更复杂,但我觉得我讲得更清楚一些。
---------- 主进程开始
1. 进程start
2. 执行函数 async1, 打印 async1 start, 碰到await async2.
3. 执行函数 async2, 打印 async2 start, 碰到await async3.
4. 执行函数 async3, 打印 async3, 并返回回调队列1,函数继续往下执行.
5. 执行Promise , 打印promise1, 并返回回调队列2, 函数继续往下执行.
6. 执行Promise , 打印promise2, 并返回回调队列3, 函数继续往下执行。
7. 进程end
--------- 主进程结束
--- 微任务开始
---------- 回调队列
8. 处理回调队列1, 执行完async3, 返回给 async2, 打印 async2 print undefined, async2 end, 返回回调队列1
9. 处理回调队列2, 打印 promise1 resolve
10. 处理回调队列3, 打印 promise2 resolve
---------- 第二次回调队列
11. 处理时间队列1, 执行完async2, 返回给 async1, 打印 async1 print undefined, async1 end, 此时回调队列为空
--- 微任务结束
--- 宏任务开始
---------- 执行事件循环
12. setTimeout1
13. setTimeout2
--- 宏任务结束
全部结束
也就是说最后执行的结果为:
进程 start
async1 start
async2 start
async3
promise1
promise2
进程 end
async2 print undefined
async2 end
promise1 resolve
promise2 resolve
async1 print undefined
async1 end
setTimeout1
setTimeout2
有不明白的欢迎留言。