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')
这道面试题主要的考点是宏任务和微任务,所以我们需要先了解宏任务和微任务。
宏任务
宏任务指执行栈中待执行的任务,计时器,事件回调,http回调
都是宏任务。
微任务
微任务指执行栈清空后立即执行的任务(VIP通道,贵族就是不一样~
),Promise 和 MutationObserver
都是微任务。
我们来分析下题目,首先从上至下依次执行
async function async1 () {
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
函数创建未执行,所以不输出;
console.log('script start');
此处第一次输出script start
;
setTimeout(function () {
console.log('setTimeout')
}, 0);
定时器,将任务放在宏任务中;
async1();
执行async1
函数,此处输出async1 start
,在async1
函数中调用async2
函数;此处输出async2
后在微队列等待执行栈完成任务后执行。
new Promise(function (resolve) {
console.log('promise1');
resolve()
}).then(function () {
console.log('promise2')
});
依次往下执行new Promise()
输出promise1
完成后,Promise.then
推送至微队列排队;
console.log('script end')
依次往下同步执行输出script end
,此时执行栈清空,开始执行微队列输出async1 end
和promise2
;微队列执行完成后执行宏队列,输出setTimeout
。
总结
- 先执行同步和立即执行任务,比如说
console.log()、new Promise()
- 再依次执行微任务,比如说
thenable
函数和catchable
函数 - 当微任务执行完成后开始执行宏任务,比如说
定时器、事件回调
等