• js 异步执行顺序


    1.js的执行顺序,先同步后异步
    2.异步中任务队列的执行顺序: 先微任务microtask队列,再宏任务macrotask队列
    3.调用Promise 中的resolve,reject属于微任务队列,setTimeout属于宏任务队列
    注意以上都是 队列,先进先出。
     
    微任务包括 `process.nextTick` ,`promise` ,`MutationObserver`。
    宏任务包括 `script` , `setTimeout` ,`setInterval` ,`setImmediate` ,`I/O` ,`UI rendering`。
    在node环境下,process.nextTick的优先级高于Promise,也就是可以简单理解为:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。
     
    javascript事件机制
     
    题目1:
     
     
    console.log('script start')  
    async function async1() {
      await async2()
      console.log('async1 end') 
    }
    async function async2() {
      console.log('async2 end')
    }
    async1()
    
    setTimeout(function() {
      console.log('setTimeout') 
    }, 0)
    
    new Promise(resolve => {
      console.log('Promise') 
      resolve()
    })
    .then(function() {
      console.log('promise1') 
    })
    .then(function() {
      console.log('promise2') 
    })
    
    console.log('script end') 
    

    执行结果?

    分析:

    首先执行 同步代码:

    1. 首先执行    console.log('script start')
    2. 执行 async1() 的时候,马上执行了 async2函数:console.log('async2 end')
    3. 顺序执行 new Promise()中的同步函数:console.log('Promise')
    4. 最后执行  console.log('script end')。
    上面是同步执行的代码,然后看剩下的异步执行的代码:
    首先,setTimeout是 宏观任务,排除到最后,剩下微观任务:
    async function async1() {
      await async2()
      console.log('async1 end') 
    }
    new Promise(resolve => {
      resolve()
    })
    .then(function() {
      console.log('promise1') 
    })
    .then(function() {
      console.log('promise2') 
    })
    

    5. 然后根据先入先出的对列方式,先执行  await async2() 后面阻碍的函数  console.log('async1 end') 

    6. 执行promise的resolve函数

    new Promise(resolve => {
      resolve()
    })
    

    也就是接下来的两个then: console.log('promise1') ----  console.log('promise2') ;

    7. 最后执行的是 setTimeout函数  console.log('setTimeout') ;

    综上所述,以上代码执行的顺序是:

    1.script start 2.async2 end 3.Promise 4.script end 5.async1 end 6.promise1 7.promise2 8.setTimeout
     
    题目2:
     
    (function() {
    
        setTimeout(() => {
            console.log(0);
        });
    
        new Promise(resolve => {
            console.log(1);
    
            setTimeout(() => {
                resolve();
                Promise.resolve().then(() => console.log(2));
                console.log(3);
            });
    
            Promise.resolve().then(() => console.log(4));
    
        }).then(() => {
            console.log(5);
            Promise.resolve().then(() => console.log(8)); 
            setTimeout(() => console.log(6));
        });
    
        console.log(7);
    
    })();
    

    1. 同样先执行同步代码,且先把setTimeout去掉:

    new Promise(resolve => {
          console.log(1);
          Promise.resolve().then(() => console.log(4)); //微观任务
      }).then(() => {                  //then函数是执行对应的 resolve 的时候才执行的
          console.log(5);
          Promise.resolve().then(() => console.log(8));//微观任务
     }); console.log(7);
    

    可以看出先执行: console.log(1);console.log(7);

    2. 执行微任务  Promise.resolve().then(() => console.log(4)); 

    代码变成了:

    (function() {
      setTimeout(() => {
          console.log(0);
      });
      new Promise(resolve => {
          setTimeout(() => {
              resolve();
              Promise.resolve().then(() => console.log(2));
              console.log(3);
          });
      }).then(() => {
          console.log(5);
          Promise.resolve().then(() => console.log(8)); //这句是多加的
          setTimeout(() => console.log(6));
      });
    })();
    

    只剩下宏观任务(微观任务在宏观任务里,也就是宏观任务外面不在有微观任务了)

    3. 执行  console.log(0);

    4.再执行 new Promise 中的  setTimeout,先执行里面的同步函数:console.log(3)

    5. 再执行上面的 resolve,对应的是下面的then函数:

    then(() => {
          console.log(5);
          Promise.resolve().then(() => console.log(8)); //这句是多加的
          setTimeout(() => console.log(6));
     }

    所以先执行 console.log(5);

    剩下的都是微观任务和宏观任务,先看微观任务:

     new Promise(resolve => {
          resolve();
          Promise.resolve().then(() => console.log(2));
      }).then(() => {
          Promise.resolve().then(() => console.log(8));
          setTimeout(() => console.log(6));
      });

    所以根据队列中的微观任务顺序先执行:console.log(2),在执行then中的 console.log(8);

    最后再执行 console.log(6)

    综上所述,结果为 

    1/7/4/0/3/5/2/8/6
     
    题目3:
    (function() {
        setTimeout(() => {
            console.log(0);
        });
    
        new Promise(resolve => {
    
            console.log(1);
            
            setTimeout(() => {
                resolve();
                Promise.resolve().then(() => {
                    console.log(2);
                    setTimeout(() => console.log(3));
                    Promise.resolve().then(() => console.log(4));
                });
            });
    
            Promise.resolve().then(() => console.log(5));
    
        }).then(() => {
    
            console.log(6);
            Promise.resolve().then(() => console.log(7));
            setTimeout(() => console.log(8));
    
        });
    
        console.log(9);
    })();
    解释如下:【同步>异步;微任务>宏任务】
    第一步:打印出1、9 ;如图
     
    图a
    由图a中的任务队列可知:
    第二步: 执行微任务3,打印出 5
    第三步:执行宏任务1,打印出 0
    第四步:开始执行宏任务2;如图:
    图b
    第五步:由图b中的任务队列可知, 执行微任务4,打印出 6,如图:
    图c
    第六步:由图c中的任务队列可知, 执行微任务5,打印出2;如图 
    图d
     

    由图d的任务队列可知,
    第七步:执行微任务6,打印出7
    第八步:执行微任务9,打印出4
    第九步:执行宏任务7,打印出8;
    第十步:执行宏任务8,打印出3;

    即答案是:

    1-9-5-0-6-2-7-4-8-3

      

  • 相关阅读:
    路由器的配置
    逻辑卷
    valn配置
    交换分区和虚拟内存
    TCP和UDP
    语法练习1
    oracl通用函数
    AOP
    oracle查询操作
    Oracle中的转换函数
  • 原文地址:https://www.cnblogs.com/chenyablog/p/11349151.html
Copyright © 2020-2023  润新知