javascript的async,await的宏任务和微任务的执行顺序
首先我们看一段代码
async function fun1 (){
await fun2();
console.log('await阻塞后的')
}
function fun2(){
return 123456;
// return 111;
}
fun1();
setTimeout(()=>{
console.log('宏任务')
},0)
new Promise((reslove)=>{
reslove(2)
}).then((res)=>{
console.log(res,'第二个 promise')
})
//执行结果
//await阻塞后的
//2 '第二个 promise'
//宏任务
上面这一段代码主要是看 ‘第二个promise’ 和 ‘await阻塞后的’ 打印顺序,因为await后面的所有代码都会会包裹成一个promise,那么看打印结果知道await func2 被包裹成的promise一定是要先比 ‘第二个 promise’ 先放入微任务队列中的。
再看下面一段代码
async function fun1 (){
await fun2();
console.log('await阻塞后的')
}
function fun2(){
return new Promise((res1)=>{
console.log('执行了内部promise')
res1('promise内部')
}).then((res)=>{
console.log(res)
return 123456789
}).then((res)=>{
console.log('内部promise结束',res)
return 'end'
})
}
fun1();
setTimeout(()=>{
console.log('宏任务')
},0)
new Promise((reslove)=>{
reslove(2)
}).then((res)=>{
console.log(res,'第二个 promise')
})
//执行结果
//执行了内部promise
//promise内部
//2 '第二个 promise'
//内部promise结束 123456789
//await阻塞后的
//宏任务
再看这上面这段代码,会发现如果return的是一个promise的话,那么执行顺序会发生变化。这里我给大家说一下是为什么。当return的是一个promise时,就会先把这个return的promise塞入到微任务队列中,等这个promise在微队列任务执行完成后,才会去把await func2包裹成的promise放入到微任务队列中去。
得出结论,如果返回的不是promise,那么await func2包裹成的promise会被直接塞入到微任务队列中去,如果返回的是promise,那么会先将这个返回的promise塞入到微任务队列中去,等全部执行完成后,再将await func2包裹成的promise塞入到微任务队列中。
再看下面这段代码
async function fun1 (){
await fun2();
console.log('await阻塞后的')
}
function fun2(){
new Promise((res1)=>{
console.log('执行了内部promise')
res1('promise内部')
}).then((res)=>{
console.log(res)
return 123456789
}).then((res)=>{
console.log('内部promise结束',res)
return 'end'
})
}
fun1();
setTimeout(()=>{
console.log('宏任务')
},0)
new Promise((reslove)=>{
reslove(2)
}).then((res)=>{
console.log(res,'第二个 promise')
})
//执行结果
//执行了内部promise
//promise内部
//await阻塞后的
//2 '第二个 promise'
//内部promise结束 123456789
//宏任务
看上面这段代码发现执行结果又变了。根据上面的结论我们可以看出fun2根本没有返回值,那么没有返回值的情况下,是不用等内部promise执行完成的,仅仅是因为内部promise的then先被放入了微任务队列,然后才执行到了 await func2包裹成的promise被放入队列,这里千万不要搞混了。
如果我们给 func2加上async呢
async function fun1 (){
await fun2();
console.log('await阻塞后的')
}
async function fun2(){
return new Promise((res1)=>{
console.log('执行了内部promise')
res1('promise内部')
}).then((res)=>{
console.log(res)
return 123456789
}).then((res)=>{
console.log('内部promise结束',res)
return 'end'
})
}
fun1();
setTimeout(()=>{
console.log('宏任务')
},0)
new Promise((reslove)=>{
reslove(2)
}).then((res)=>{
console.log(res,'第二个 promise')
})
//执行结果
//执行了内部promise
//promise内部
//2 '第二个 promise'
//内部promise结束 123456789
//await阻塞后的
//宏任务
async function fun1 (){
await fun2();
console.log('await阻塞后的')
}
async function fun2(){
// return new Promise((res1)=>{
// console.log('执行了内部promise')
// res1('promise内部')
// }).then((res)=>{
// console.log(res)
// return 123456789
// }).then((res)=>{
// console.log('内部promise结束',res)
// return 'end'
// })
return 123456
}
fun1();
setTimeout(()=>{
console.log('宏任务')
},0)
new Promise((reslove)=>{
reslove(2)
}).then((res)=>{
console.log(res,'第二个 promise')
})
//执行结果
//await阻塞后的
//2 '第二个 promise'
//宏任务
会发现加上async和不加async的执行流程是没有变化的
再看下面这段代码
async function fun1 (){
await fun2();
console.log('await阻塞后的')
}
async function fun2(){
// return new Promise((res1)=>{
// console.log('执行了内部promise')
// res1('promise内部')
// }).then((res)=>{
// console.log(res)
// return 123456789
// }).then((res)=>{
// console.log('内部promise结束',res)
// return 'end'
// })
return await '123456'
}
fun1();
setTimeout(()=>{
console.log('宏任务')
},0)
new Promise((reslove)=>{
reslove(2)
}).then((res)=>{
console.log(res,'第二个 promise')
})
//执行流程
//2 '第二个 promise'
//await阻塞后的
//宏任务
会发现我在fun2中又加了个await,其实加了await就是相当于返回了一个promise,返回了promise就得先把返回的promise执行完。所有执行流程变了