js红任务微任务事件轮巡的面试题
今天记录下一个关于js宏任务、微任务、事件轮巡机制的经典面试题:
async function async1(){
console.log("1");
await async2();
// async2();
console.log("2");
}
async function async2(){
console.log("3");
}
console.log("4");
setTimeout(() => {
console.log("5");
Promise.resolve().then(function(){
console.log("6");
});
}, 0);
setTimeout(() => {
console.log("7");
Promise.resolve().then(function(){
console.log("8");
});
}, 0);
async1();
new Promise(function(resolve){
console.log("9");
resolve();
}).then(function(){
console.log("10");
});
console.log("11");
//断言输出顺序
// 4 => 1 => 3 => 9 => 11 => 10 => 2 => 5 => 7 => 6 => 8
//结果
// 4 => 1 => 3 => 9 => 11 => 2 => 10 => 5 => 6 => 7 => 8
这种东西,你当时看看可能就明白了。过两天就又忘了,所以写两遍看两遍可能记得牢点,然后看代码执行顺序:
(其实只要记住,宏任务是一个一个的执行,微任务是一下子全执行,执行完一个宏任务就去清空一下微任务栈,一步一步分析就OK。但前提你得知道哪些是宏任务哪些是微任务)
第一遍下来:4 => 将两个settimeout放入宏任务任务栈 => 1 => 3 然后将await后边的放入微任务栈 => 9 => 将then里的放入微任务栈 => 11;
然后清空微任务栈:2 => 10;
然后执行宏任务:这时候宏任务里边放着两个settimeout,先执行第一个:5=>将后面紧跟着的then放入微任务栈,
然后清空微任务栈:6;
然后执行宏任务:执行另一个宏任务:输出7 => 将then后边的放入微任务栈中;
然后清空微任务栈:8;
当然这个是我看完运行结果之后分析的,现在说下我出错的两个地方,第一个简单就是settimeout里边加Promise这里:大意了,执行settimeout之前微任务栈是空的,执行之后微任务栈就有东西了,自己放的。然后看第二个出错的地方是:Promise的then和await之后的谁优先,记得在哪里看到过:说then比await优先级高,是真的吗?
function test2(){ async function async1(){ console.log("1"); await fn(); console.log("2"); } function fn(){ console.log("3"); } async1(); new Promise((resolve,reject)=>{ console.log("4"); resolve(); }).then(_=>{ console.log("5"); }); } // test2(); // 断言 13425 // 结果13425
看来不是真的,但我真的记得遇见过呀!?
还找到了:
但是我运行下:
function test3(){ 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') } test3(); // 断言 script start => async1 start => async2 => promise1 => script end => async1 end => promise2 => setTimeout // 运行 script start => async1 start => async2 => promise1 => script end => async1 end => promise2 => setTimeout
和他说的不一样!用node运行也是一样!
然后一顿找:发现这个和运行环境的版本有关系,所以就不必过于深究了!WTF!
over!