一次性完全瞭解js event loop 事件循環

js事件大體能夠分爲微任務,宏任務,同步任務,異步任務html

1,微任務 Promise.then()  [非promise]   ,  process.nextTrick()    [node中]  等等...node

2,宏任務  setTimeout()  html總體代碼 setInterval()  等等...面試

3,異步任務  setTimeout()  setInterval() ajax請求  等等...ajax

4,同步任務  [這個不知道怎麼舉例...]  promise

eg:
    //微任務 - 同步任務
    new Promise((resolve,reject)=>{   //tip:promise是同步任務
        console.log(1);               
        resolve();
    })
    .then(()=>{                        // promise.then()是微任務
        console.log(2)
    })

    //打印結果
    1;
    2;
    

    /*
        首先咱們先了解js執行機制,因爲js是單線程任務,會有一個event loop循環機制,
        因此會一步一步執行,
        也就是隊列,而執行時先執行宏任務,等到宏任務執行完執行在執行微任務,
        例如上面的例子:
        先將同步任務pormise放入隊列執行[輸出1] => 發現resolve(.then說你執行完了,該我了) 
                                                同步任務執行完畢
                                             => 執行微任務[輸出2]
    */複製代碼

eg:
    //異步任務 - 宏任務
    console.log(1);        //同步任務
    setTimeout(()=>{       // 宏任務-異步任務
        console.log(2)
    })
    console.log(3)

    /*
        首先將console.log(1)放入event loop循環機制裏 打印1
         =>         發現宏任務,且宏任務是異步的,將setTimeout放入event loop循環中

          =>
        
         發現同步任務console.log(3),將console.log(3)放入event loop執行,
    
          並將同步任務放在異步任務以前執行  打印3

        =>
    
        同步任務執行完,異步任務,大家都完事了,該我了吧. 打印3
        
    */
複製代碼

來看一道有趣的面試題bash

console.log(1);

setTimeout(function(){
    console.log(2)
})

new Promise(function((resolve,reject)=>{
    console.log(3);
})
.then(()=>{
    console.log(4)
});




/*
       首先咱們來分析下這道題,
        
       發現事件,開啓event loop循環機制

        =>

       先將console.log(1)放入event loop 循環機制中
    
        =>
        
        發現宏任務,將setTimeout放入event loop循環機制中,
        
        發現宏任務setTimeout 是異步任務, 給他單獨開條路,讓他執行

        =>
    
        發現同步任務promise, 將同步任務放入event loop 循環機制中

         打印結果依次爲[1 => 3 => 2 ]

        這裏解釋一下爲何微任務promise().then()沒有執行

        [在執行同步任務promise時,沒有發現resolve()函數,所以沒法繼續向下執行,

         promise()一直處於pedding狀態,若是在同步任務promise()中加了resolve()函數

         那麼微任務promise().then()會執行,打印結果依次爲[1 => 3 => 4 => 2]
         
          這樣不少人會說,setTimeout不是宏任務嗎? 不是宏任務先執行嗎? 

            解釋一下,setTimeout是宏任務可是他是異步任務,異步任務會等到線程上的任務都結束

            以後纔會輸出.
         ]

        
*/

複製代碼

eg:
    //下面看下這道題的進階版本

    console.log(1);   setTimeout(function(){
       console.log(2);
        new Promise((resolve,reject) =>{
            console.log(3);
            resolve();
            console.log(4)
        })
        .then(()=>{
            console.log(5)
        })     
   })
    
    console.log(6);


    /*
        
        第一步:發現事件 -> 開啓event loop 事件循環機制 

        第二步:將同步任務console.log(1)放入event loop事件循環中  - >  [打印  1]
        第三步:發現宏任務且是異步 -> 將setTimeout放入event loop事件循環中,

                等到線程同步任務結束在開始執行    

        第四步:發現同步任務console.log(6),將同步任務console.log(6)放入event loop事件循環中 [打印6]
        第五步:setTimeout異步宏任務發現js線程同步任務結束,終於輪到我執行了吧,將setTimeout放入js線程

        第六步:執行setTimeout宏任務 首先發現同步任務 console.log(2)將其放入event loop事件循環機制中,

        第七步:發現同步微任務promise(),將promise()放入event loop 事件循環中
    
        第八步:進入promise()微任務 ,放入event loop事件循環中 ->  發現同步任務console.log(3) [打印3]
        
        第九步:發現resolve() ->  promise().then()  能夠向下執行

        第十步:發現同步任務console.log(4),將其放入event loop事件循環中  [打印4]

        第十一步:同步任務執行完,執行微任務promise().then() ->  [打印  ->  5]

        第十二步:js 線程上沒有任務,結束event loop 事件循環
        
        至此結束, 打印結果依次爲[ 1 -> 6 -> 2 -> 3 -> 4 -> 5    ]
    */複製代碼

至此,你明白了js event loop 事件循環了嗎?異步

相關文章
相關標籤/搜索