//请写出输出内容
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(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
*/
以上代码的执行顺序如上图,请解释下为什么执行顺序是这样的。我先说一下我的理解(可以忽略,直接回答问题),当然我的想法是错误的,请大佬指正。
1、首先执行第一个宏任务script,遇到setTimeout,属于第二个宏任务,加入宏任务队列,再遇到同步任务console.log('script start'),直接输出script start
;
2、然后在遇到async1(),async1中await之前的代码也属于同步任务,于是输出async1 start
,接下来遇见await async2(),这里属于微任务,于是加入微任务队列;
3、然后再遇到new Promise,new Promise里边resolve的之外代码会立即执行,输出promise1
,then里边的代码属于微任务,于是继续往下;
4、遇到console.log('script end'),属于同步任务,于是输出script end
,到此第一个宏任务执行完毕;
5、于是开始执行所有微任务,按顺序,先执行async2(),于是输出async2
;
6、await执行完毕,输出async1 end
;
7、然后执行第二个微任务,输出promise2
;
8、最后再执行第二个宏任务setTimeout,输出setTimeout
。
代码中需要执行的步骤:
js是异步I/O,事件驱动,当执行到需要异步回调的时候,js主线程不阻塞在这里,继续执行后面代码,之后异步完成,执行回调。
而setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,所以这里会放在任务队列的最后执行。