标签:结果 star on() 参考 任务队列 one rom resolve 异步回调
async其实就是对Generator的封装,只不过async可以自动执行next()。
async必须等到里面所有的await执行完,async才开始return,返回的Promise状态才改变。除非遇到return和错误。
async默认返回一个Promise,如果return不是一个Promise对象,就会被转为立即resolve的Promise,可以在then函数中获取返回值。
async function async1() {
console.log("async1_start_2");
await async2();
console.log("async1_end_6");
return ‘async_return_8‘;
}
async function async2() {
console.log("async2_3");
}
console.log("script_start_1");
setTimeout(function() {
console.log("setTimeout_9");
}, 0);
async1().then(function (message) { console.log(message) });
new Promise(function(resolve) {
console.log("promise_4");
resolve();
}).then(function() {
console.log("promise_7");
});
console.log("script_end_5");
输出为:
这道题目考查的是我们对 事件循环 任务队列 的理解:
事件循环(Event Loop):
[ 分析 ]:
在单线程的js中,异步代码会被放入一个事件队列,等到所有其他代码执行后再执行,而不会阻塞线程。我们从上到下看,首先打印:1
;
setTimeout / setInterval 要放到任务队列的末尾,等待后续执行。继续往下走;
此时的任务队列:
async1 开始执行,当函数里遇到await时,暂停执行(await所在行放在本次执行完),而 async1 函数 未完成部分被添加到宏任务队列;
此时的任务队列:
new Promise() 实例对象被new出来后,它里面的promise1会立刻打印,然后又遇到 then, 此时 promise 实例 被添加到微任务队列;
此时的任务队列:
接着打印:script end。至此,同步代码(第一个宏任务)已执行完毕。而我们的任务队列中还存在着 async1, promise对象, setTimeout异步回调;
由于异步代码第一次执行时,async1 函数 要早于 promise对象,所以紧接着 async1 函数继续执行没有执行完成的部分,执行完毕后,退出任务队列,打印:async1 end。然后把它的 then 逻辑添加到任务微任务队列中;
? 此时的任务队列:
宏任务队列:setTimeout
微任务队列:promise实例 ,async1的then逻辑部分
? 此时的任务队列:
宏任务队列:setTimeout
微任务队列:async1的then逻辑部分
? 此时的任务队列:
宏任务队列:setTimeout
微任务队列:none
console.log(1);
async function asyncfn1(){
console.log(2);
await asyncfn2();
console.log(5);
};
setTimeout(() => {
console.log(‘setTimeout‘)
}, 0)
async function asyncfn2(){
console.log(3)
};
asyncfn1();
console.log(4);
输出:
细品:
1
;asyncfn1
,输出 2
遇到awati
后,先执行asyncfn2
,将后面的代码放入宏任务队列,此时的任务队列:
asyncfn1
剩余代码;asyncfn2
输出 3
;4
;5
;var p = new Promise((res,rej) => {
res(‘hello_6‘)
console.log(‘1‘)
})
function hello() {
console.log(‘hello_begins_2‘)
return p
}
hello().then(res => {
console.log(res)
console.log(‘hello_7‘)
return ‘hello_10‘
}).then(res => {
console.log(res)
console.log(‘hello_11‘)
return ‘hello_13‘
}).then(res => {
console.log(res)
console.log(‘hello_14‘)
})
function test1 () {
console.log(‘test1_5‘)
}
async function asy () {
console.log(‘asy_begins_3‘)
await console.log(‘asy_4‘)
console.log(‘async_8‘)
await console.log(‘asy_9‘)
console.log(‘asy_ends_12‘)
}
asy()
test1()
结果:
看官们可以根据输出结果细品;
注意:await
后面的代码虽然算作宏任务,但是和普通的微任务不在一个维度,位于更上一层的任务队列,所以优先度要比其他(下层)微任务要高;
参考思路:
1
(遇到new Promise()的需要立即执行)11
行执行 hello
函数,输出2
,并返回一个Promise
对象p
,将hello函数的第一层then函数放入微任务队列;此时的任务队列:
宏任务队列:none
微任务队列:hello.then
38
行,执行asy
函数;29
行输出3
,随后遇到await
,执行该行,输出4
,剩下的代码被放入了宏任务队列(为了区分任务的层次,标明了序号,先执行完同层的任务,再到其他层)此时的任务队列:
宏任务队列:asy await后代码(0)
微任务队列:hello.then(0),hello.then.then(1),hello.then.then.then(2)
5
;6
(第12->8->2行),随后第13行输出7
;此时的任务队列:
宏任务队列:asy await后代码(0)
微任务队列:hello.then.then(1),hello.then.then.then(2)
32
行输出8
,第39
行遇到await,执行完该行输出9
后,将后面的代码推进宏任务队列;此时的任务队列:
宏任务队列:asy await后代码(1)
微任务队列:hello.then.then(1),hello.then.then.then(2)
15
行,执行hello函数的第二个then函数,返回处理结果res,输出10
和11
;此时的任务队列:
宏任务队列:asy await后代码(1)
微任务队列:hello.then.then.then(2)
35
行,输出12
;此时的任务队列:
宏任务队列:none
微任务队列:hello.then.then.then(2)
19
行输出hello的第二个then函数的处理结果,分别是13
和14
;至此程序执行完成;
标签:结果 star on() 参考 任务队列 one rom resolve 异步回调
原文地址:https://www.cnblogs.com/AhuntSun-blog/p/13584169.html