遇到setTimeout,扔到下一轮的宏任务队列里。会等当前这轮Eventloop完成,再去第二轮执行。
遇到new Promise,里边的异步操作是马上执行的,但是then里的回调函数,被扔到微任务队列里。注意,必须是then前边的promise实例里边的异步操作全部完成了,then里边的回调才会在当下被放进微任务队列里。即,在promise实例里,如果执行了resolve(),它只表示要执行then里的第一个函数,它只会指定,不会把then里的回调放进队列。那什么时候放呢?promise实例全都执行完了,得到了,接着执行then的时候,才会把then里的回调放进微任务队列里。
在async函数里,遇到await,先去执行await接着的函数,执行完以后,await会让出线程,把await后边,还是async内部的语句放进微任务队列里。
让本轮所有同步代码执行完毕,会去微任务队列里,依次取出,执行。等微任务队列里的全都执行完了,这轮就完成了。
然后在下一轮的宏任务队列里找,依次执行。
例1:
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
return 'async return';
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(function() {
console.log("setTimeout");
}, 0);
async1().then(function (message) { console.log(message) });
new Promise(function(resolve) {
console.log("promise1");
resolve();
}).then(function() {
console.log("promise2");
});
console.log("script end");
比如,async1().then 这里,去执行async1函数,在里边遇到await,所以后边的两行代码会被放进微任务队列里,所以async1函数还没执行完。所以then里边的回调不会现在被放进微任务队列。而是等async1里的全部代码执行完,才会被放进微任务队列里。
分析过程:
"script start"
console.log("setTimeout");-下一轮宏任务
"async1 start"
"async2"
console.log("async1 end"); -微任务1
return 'async return'; -微任务2
"promise1"
console.log("promise2"); -微任务3
"script end"
"async1 end" 1完成
function (message) { console.log(message) } -微任务4
"promise2" 3完成
'async return' 4完成
"setTimeout"
所以最终顺序:
"script start"
"async1 start"
"async2"
"promise1"
"script end"
"async1 end"
"promise2"
"async return"
"setTimeout"
例2:
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('setTimeout1');
}, 200);
setTimeout(function() {
console.log('setTimeout2');
new Promise(function(resolve) {
resolve();
}).then(function() {
console.log('then1')
})
new Promise(function(resolve) {
console.log('Promise1');
resolve();
}).then(function() {
console.log('then2')
})
},0)
async1();
new Promise(function(resolve) {
console.log('promise2');
resolve();
}).then(function() {
console.log('then3');
});
console.log('script end');
分析:
'script start'
200 setTimeout-宏任务队列
0 setTimeout-宏任务
'async1 start'
'async2'
await让出线程,console.log('async1 end'); -微任务队列
'promise2'
function() {
console.log('then3');
} -微任务队列
'script end'
取出微任务:
'async1 end'
'then3'
下一轮宏任务:0ms先执行
'setTimeout2'
console.log('then1') -微任务队列
'Promise1'
console.log('then2') -微任务队列
'then1'
'then2'
200ms 执行
'setTimeout1'
最终顺序:
"script start"
"async1 start"
"async2"
"promise2"
"script end"
"async1 end"
"then3"
"setTimeout2"
"Promise1"
"then1"
"then2"
"setTimeout1"