美文网首页
JS事件循环机制---宏任务/微任务

JS事件循环机制---宏任务/微任务

作者: 如你眉间山水 | 来源:发表于2019-12-16 15:47 被阅读0次
    image

    微任务和宏任务皆为异步任务,但微任务优先级高于宏任务

    例子1

    console.log('script start');
    
    setTimeout(function() {
      console.log('setTimeout');
    }, 0);
    
    Promise.resolve().then(function() {
      console.log('promise1');
    }).then(function() {
      console.log('promise2');
    });
    
    console.log('script end');
    

    执行结果为 script start, script end, promise1, promise2, setTimeout
    因为Promise是微任务,主线程会在同步任务做完后清空微任务队列,再执行宏任务队列里的setTimeout

    例子2

    Promise.resolve().then(()=>{
      console.log('Promise1')  
      setTimeout(()=>{
        console.log('setTimeout2')
      },0)
    })
    
    setTimeout(()=>{
      console.log('setTimeout1')
      Promise.resolve().then(()=>{
        console.log('Promise2')    
      })
    },0)
    

    执行结果为:Promise1,setTimeout1,Promise2,setTimeout2

    step1:
    同步任务执行完毕,会去清空微任务,输出Promise1,同时生成宏任务 setTimeout1,setTimeout2
    step2:
    去宏任务队列查看,此时队列最前面是 setTimeout1 ,所以执行setTimeout1,同时生成微任务Promise2
    step3:
    宏任务结束后再去查看微任务队列,执行Promise2
    step4:
    微任务结束后再执行最后一个宏任务setTimeout2

    例子3

     setTimeout(function(){
         console.log('定时器开始啦')
     });
     
     new Promise(function(resolve){
         console.log('马上执行for循环啦');
         for(var i = 0; i < 10000; i++){
             i == 99 && resolve();
         }
     }).then(function(){
         console.log('执行then函数啦')
     });
     
     console.log('代码执行结束');
    

    【马上执行for循环啦 --- 代码执行结束 --- 执行then函数啦 --- 定时器开始啦】

    执行同步任务 依次打印 '马上执行for循环啦','代码执行结束' 然后依次微任务、宏任务

    首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里
    
    遇到 new Promise直接执行,打印"马上执行for循环啦"
    
    遇到then方法,是微任务,将其放到微任务的【队列里】
    
    打印 "代码执行结束"
    
    本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数啦"
    
    到此,本轮的event loop 全部完成。
    
    下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"
    

    例子4

    setTimeout(() => console.log('setTimeout1'), 0);  //1宏任务
    setTimeout(() => {                              //2宏任务
        console.log('setTimeout2');
        Promise.resolve().then(() => {
            console.log('promise3');
            Promise.resolve().then(() => {
                console.log('promise4');
            })
            console.log(5)
        })
        setTimeout(() => console.log('setTimeout4'), 0);  //4宏任务
    }, 0);
    setTimeout(() => console.log('setTimeout3'), 0);  //3宏任务
    Promise.resolve().then(() => {//1微任务
        console.log('promise1');
    })
    

    [promise1--setTimeout1--setTimeout2-- promise3--5--promise4--setTimeout3--setTimeout4]

    例子5

    async function async1() {
        console.log( 'async1 start' )
        await async2()
        console.log( 'async1 end' )
    }
    async function async2() {
        console.log( 'async2' )
    }
    async1()
    console.log( 'script start' )
    
    执行结果
    async1 start
    async2
    script start
    async1 end
    

    例子6

           async function async1() {
                console.log( 'async1 start' ) //2
                await async2()
                console.log( 'async1 end' )//6
            }
    
            async function async2() {
                console.log( 'async2' )//3
            }
    
            console.log( 'script start' ) //1
    
            setTimeout( function () {
                console.log( 'setTimeout' )//8
            }, 0 )
    
            async1();
    
            new Promise( function ( resolve ) {
                console.log( 'promise1' )//4
                resolve();
            } ).then( function () {
                console.log( 'promise2' ) //7
            } )
            console.log( 'script end' )//5
    

    [script start--async1 start--async2--promise1--script end--async1 end-- promise2-- setTimeout]
    首先:


    image

    所以输出顺序是:


    image

    例子7

     new Promise( ( resolve, reject ) => {
                    console.log( "promise1" )
                    resolve()
                } )
                .then( () => {
                    console.log( 1 )
                } )
                .then( () => {
                    console.log( 2 )
                } )
                .then( () => {
                    console.log( 3 )
                } )
    
            new Promise( ( resolve, reject ) => {
                    console.log( "promise2" )
                    resolve()
                } )
                .then( () => {
                    console.log( 4 )
                } )
                .then( () => {
                    console.log( 5 )
                } )
                .then( () => {
                    console.log( 6 )
                } )
            // 1 4 2 5 3 6
    

    先执行同步代码 promise1, promise2,此时微任务有两个任务 log(1)和log(4)

    执行完log(1)和log(4)此时任务中有log(2)和log(5)两个微任务

    执行log(2)和log(5)此时任务中有log(3)和log(6)两个微任务

    例子8 执行环境栈

    function foo(i) {
      if (i < 0) return;
      console.log('begin:' + i);
      foo(i - 1);
      console.log('end:' + i);
    }
    foo(2);
    
    // 输出:
    
    // begin:2
    // begin:1
    // begin:0
    // end:0
    // end:1
    // end:2
    // 执行栈既是函数在执行时存储调用过程的栈,同样的,采取调用形式进行队列,先进后出的方式
    

    例子9

    async function t1 () {
      console.log(1)
      console.log(2)
      await Promise.resolve().then(() => console.log('t1p'))
      console.log(3)
      console.log(4)
    }
    
    async function t2() {
      console.log(5)
      console.log(6)
      await Promise.resolve().then(() => console.log('t2p'))
      console.log(7)
      console.log(8)
    }
    
    t1()
    t2()
    
    console.log('end')
    
    // 输出:
    // 1
    // 2
    // 5
    // 6
    // end
    // t1p
    // t2p
    // 3
    // 4
    // 7
    // 8
    // undefined
    
    async function t1 () {
      console.log(1)
      console.log(2)
      await new Promise(resolve => {
        setTimeout(() => {
          console.log('t1p')
          resolve()
        }, 1000)
      })
      await console.log(3)
      console.log(4)
    }
    
    async function t2() {
      console.log(5)
      console.log(6)
      await Promise.resolve().then(() => console.log('t2p'))
      console.log(7)
      console.log(8)
    }
    
    t1()
    t2()
    
    console.log('end')
    
    // 输出:
    // 1
    // 2
    // 5
    // 6
    // end
    // t2p
    // 7
    // 8
    // undefined
    // t1p
    // 3
    // 4
    

    相关文章

      网友评论

          本文标题:JS事件循环机制---宏任务/微任务

          本文链接:https://www.haomeiwen.com/subject/urrdnctx.html