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!

 

posted on 2020-09-12 20:41  rainbowLover  阅读(1044)  评论(1编辑  收藏  举报