• 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
  • 相关阅读:
    数据库系统原理:范式理论
    数据库系统原理:MVCC
    数据库系统原理:悲观锁、乐观锁
    数据库系统原理:封锁
    数据库系统原理:四大隔离级别
    数据库系统原理:ACID的作用以及实现原理
    计算机网络HTTP:长连接与短连接
    计算机网络HTTP:HTTP缓存
    计算机网络HTTP:状态码
    yum安装Docker
  • 原文地址:https://www.cnblogs.com/xiaozhumaopao/p/11066005.html
Copyright © 2020-2023  润新知