asyncawait执⾏原理详解
⼀、概述
1.明确概念
async函数就是generator函数的语法糖。
async函数,就是将generator函数的*换成async,将yield替换成await。
【async函数对generator的改进】
(1)内置执⾏器,不需要使⽤next()⼿动执⾏。
(2)await命令后⾯可以是Promise对象或原始类型的值,yield命令后⾯只能是Thunk函数或Promise对象。
(3)返回值是Promise。返回⾮Promise时,async函数会把它包装成Promise返回。(solve(value))
2.作⽤
await和async使用方法
异步编程的终极解决⽅案。
3.通俗理解(个⼈理解)
async/await,就是异步编程回调函数写法的替代⽅法。(使代码以同步⽅式的写法完成异步操作)
⼆、执⾏顺序
1.原理
函数执⾏时,⼀旦遇到await就会返回。等到触发的异步操作完成(并且调⽤栈清空),再接着执⾏函数体内后⾯的语句。
【个⼈理解】
【个⼈理解
await语句后⾯的代码,相当于回调函数。(即:await的下⼀⾏开始,都视作回调函数的内容)
回调函数会被压⼊microtask队列,当主线程调⽤栈被清空时,去microtask队列⾥取出各个回调函数,逐个执⾏。
await只是让当前async函数内部、后⾯的代码等待,并不是所有代码都卡在这⾥。遇到await就先返回,执⾏async函数之后的代码。
2.await执⾏细节
(2019.8.20测试发现:浏览器实际执⾏结果发⽣变化。await后⾯的函数,⽆论返回promise、还是⾮promise,执⾏结果都与曾经返回⾮promise相同)
主线程执⾏过程中,遇到await后⾯的函数调⽤,会直接进⼊函数,并执⾏。
(1)当这个函数返回⾮promise:
await后⾯的代码被压⼊microtask队列。当主线程执⾏完毕,取出这个回调,执⾏。
(2)当这个函数返回promise:—— 这种情况,看浏览器实际表现,已经不是这样处理了。
await后⾯的代码被压⼊microtask队列。当主线程执⾏完毕,取出这个回调,发现await语句等待的函数返回了promise,把后续代码赋给这个
promise对象的then,并把这个promise的回调再压⼊microtask队列,重新排队。当它前⾯的回调函数都被取出执⾏后,再取出它,执⾏。
三、栗⼦
await返回⾮promise
【No1】await返回⾮promise
async function func1(){
console.log('func1');
var a = await func2(); //当await返回⾮promise
console.log('func1 return');
}
function func2(){
console.log('func2');
} //返回undefined
func1();
new Promise(function(resolve){
console.log('promise1');
resolve('resolved');
}).then(function(data){
console.log(data);
});
结果:
func1
func2
promise1
func1 return
resolved
【No2】await返回promise
await返回promise
async function func1(){
console.log('func1');
var a = await func2(); //当await返回promise
var a = await func2(); //当await返回promise
console.log('func1 return');
}
async function func2(){
console.log('func2');
} //返回promise
func1();
new Promise(function(resolve){
console.log('promise1');
resolve('resolved');
}).then(function(data){
console.log(data);
});
结果:
func1
func2
promise1
func1 return
resolved
【注】
下⾯两个粗体console顺序,原来是反过来的。2019.8.20测试,与栗⼦1中,返回⾮promise情况结果相同了
await返回promise(来⾃头条笔试题)【No3】await返回promise(来⾃头条笔试题)async function async1() {
console.log("async1 start");
await  async2();
await  async2();
console.log("async1 end");
}
async  function async2
function async2() {    async
console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log('script end');
结果:
script start
async1 start
async2
promise1
script end
async1 end
promise2
settimeout
【注】
async1 end、promise2的console顺序,原来是反过来的。2019.8.20测试,与栗⼦1中,返回⾮promise 情况结果相同了
【!!Mark】
以上均为个⼈理解,如有理解偏差,请指正,感谢。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。