下面是今日头条的前端面试题:
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() {
// setTimeout放入event-loop中的macro-tasks队列,暂不执行
console.log("setTimeout");
}, 0);
async1();
new Promise(function(resolve) {
console.log("promise1");
resolve();
}).then(function() {
console.log("promise end");
});
console.log("script end");
运行结果:
script start
async1 start
async2
promise1
script end
promise end
async1 end
setTimeout

第一步,执行同步代码:
async function async1() {
console.log("async1 start"); // 同步代码2
await async2(); // 调用async2(),async2()的返回值是promise,不执行promise的resolve,让出线程
console.log("async1 end");
}
async function async2() {
console.log("async2"); // 同步代码3
}
console.log("script start"); // 同步代码1
setTimeout(function() {
// 异步 setTimeout放入event-loop中的macro-tasks队列,暂不执行
console.log("setTimeout");
}, 0);
async1();
new Promise(function(resolve) {
console.log("promise1"); // 同步代码4
resolve();
}).then(function() {
console.log("promise end"); // 不执行
});
console.log("script end"); // 同步代码5
console.log("script start"); // 同步代码1这句代码毫无疑问是同步执行的 ;setTimeout()是异步任务,加入异步队列,不执行;- 然后调用
async1(),执行这个方法体内的同步函数,打印console.log("async1 start"); // 同步代码2; - 向下执行,遇到
await关键字,调用async2(),执行同步代码打印console.log("async2"); // 同步代码3,让出线程。await是让出当前函数线程,交给函数外的代码执行; - 线程跳出
async1(),向下执行Promise(),执行里面的同步代码打印promise1,resolve是异步函数,加入异步队列,此时继续执行同步函数,回到await关键字处,执行剩余代码; async2()是异步方法,默认返回promise,所以把返回的promise加入异步队列;- 此时没有同步任务,就去执行异步任务,因为setTimeout()的优先级低于promise,所以会优先执行promise队列。
- 此时异步队列任务顺序:
setTimeout()-new Promise().resolve()-async2().resolve(),setTimeout优先级低,所以先执行下一个,打印console.log("promise end"); - 继续执行异步任务,async2()执行完毕,同步await,这时候同步向下执行
console.log("async1 end"); - 最后执行setTimeout()。