zoukankan      html  css  js  c++  java
  • js 异步执行顺序

    参考文章:  js 异步执行顺序
     
    1.js的执行顺序,先同步后异步
    2.异步中任务队列的执行顺序: 先微任务microtask队列,再宏任务macrotask队列
    3.调用Promise 中的resolve,reject属于微任务队列,setTimeout属于宏任务队列
    注意以上都是 队列,先进先出。
     
    微任务包括 `process.nextTick` ,`promise` ,`MutationObserver`。
    宏任务包括 `script` , `setTimeout` ,`setInterval` ,`setImmediate` ,`I/O` ,`UI rendering`。
     
    题目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
     
    详细问题三:
    (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
  • 相关阅读:
    Android开发之Sqlite的使用
    ZOJ 3607 Lazier Salesgirl
    ZOJ 3769 Diablo III
    ZOJ 2856 Happy Life
    Ural 1119 Metro
    Ural 1146 Maximum Sum
    HDU 1003 Max Sum
    HDU 1160 FatMouse's Speed
    Ural 1073 Square Country
    Ural 1260 Nudnik Photographer
  • 原文地址:https://www.cnblogs.com/xiaozhumaopao/p/11066005.html
Copyright © 2011-2022 走看看