执行到 await 时,await会阻塞下面的代码,会先等到await右边跟着的表达式的结果,就是await等待的东西。

等到之后,对于await来说,也分两种情况,一种是等到的是一个promise对象,另一种是非promise对象。

如果,不是promise对象,await会阻塞下面的代码,先执行async外面的同步代码,等同步代码执行完之后,再回到async内部,把这个非promise的东西,作为await表达式的结果。

如果等到的是一个promise对象,await也会阻塞async下面的代码,先执行async外面的同步代码,等promise对象fulfilled,然后把resolve的参数作为await表达式的运算结果。

async function async1(){
	console.log('async1 start')
	await async2()
	console.log('async1 end')
}
async function async2(){
	console.log('async2')
}
console.log('script start')
setTimeout(function(){
	console.log('setTimeout')
}, 0)
async1()
new Promise(resolve => {
	console.log('promise0')
	resolve()
})
.then(()=>{
	console.log('promise1')
})
.then(()=>{
	console.log('promise2')
})
console.log('script end')

script start => async1 start => async2 => promise0 => script end => promise1 => promise2 => async1 end => setTimeout
  1. 先从上至下执行同步代码,输出 script start
  2. 遇到setTimeout异步函数,会将这个异步函数放到一个新的宏观任务表,
  3. 执行async1(),打印async1 start没什么可说的。
  4. 再执行await async2(),遇到await,会阻塞下面的代码执行,会等await右边的表达式也就是async2()执行,输出async2。
  5. await 等async2的结果为非promise对象,就会停止await async2()下面的代码执行,直接跳出async function async1()函数,执行async function async1()下面的同步函数。
  6. 此时运行到new Promise,会先执行同步代码输出promise0。
  7. .then()函数可以视为当前宏观任务表中新增了一个微任务,微任务会等当前宏观宏观任务表中的同步代码执行完再执行。所以,先输出script end,此时当前宏观任务表中的同步代码以及全部运行完成,就可以执行微任务,接着输出promise1和promise2。
  8. 此时当前任务表中的宏观任务和微任务都已经完成,就可以回到async function async1()中执行await async2()下面的代码,输出async1 end。
  9. 最后再输出setTimeout。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐