JS事件循環,瞭解一下

在理解事件循環以前,我總會遇到一些奇奇怪怪的問題:好比明明已經調接口拿到了數據,但是跟在調數據以後的操做卻沒有正常執行;又或者不知道爲啥,代碼裏非得加個setTimeout才能正常跑通;特別是在運用Promise的時候,更是有各類問題百思不得解。趕上問題要解決,更要知道問題產生的緣由,這樣才能hold住全場!前端

廢話很少說了,先來看一段代碼ajax

console.log('start');

setTimeout(function(){
   console.log('setTImeout1') 
},0);

new Promise(function(resolve,reject){
    console.log('resolve')
    setTimeout(function(){
        console.log('setTimeout2')
    },200);
    resolve()
}).then(function(){
    console.log('then')
});

setTimeout(function(){
    console.log('setTimeout3')
},0);

console.log('end');

結果是start resolve end then setTimeout1 setTimeout3 settimeout2數據結構

在分析結果以前,我先來科普幾個概念,這些概念的表述不必定與標準徹底對應,可是能夠幫助你更容易理解JS的事件機制異步

  • 宏任務(macro-task):包括js總體代碼,setTimeout,setInterval,setImmediate ,I/O, UI renderder等
  • 微任務(micro-task):包括Promise,Object.observe,process.nextTick,MutationObserver等
  • 調用棧:js被加載進來以後,會從上至下讀取代碼,同步代碼被當即執行,而異步代碼被加入事件隊列中
  • 事件隊列:一些沒有被當即執行的代碼被添加到事件隊列中,隊列是一種先進先出的數據結構,也就是說,先加入事件隊列的任務會被優先執行

咱們知道,js是單線程的,這就是說,只有一個主線程,主線程會自上而下依次執行調用棧中的事件。任務隊列中的代碼被加載到函數調用棧中去執行。當前的宏任務隊列中的代碼執行完畢後,會執行本次宏任務隊列中分發到微任務隊列中的代碼。而後執行下一個宏任務隊列中的代碼,依次循環。函數

這裏要提一點容易誤解的地方,setTimeout函數自己,實際上是當即執行的,它內部的任務,纔會被分發到任務隊列中延時執行。spa


  • 代碼被加載後,全局上下文進入函數調用棧,緊接着,‘start’被執行
  • 遇到setTimeout的時候,新建了一個宏任務隊列,函數內的任務被分發這個隊列中等待執行
  • 此時遇到了Promise,注意,Promise中的第一個function中的代碼會立馬開始執行,遇到resolve或者reject後,then方法中函數會被分發到本次事件循環的微任務隊列中等待執行。因此這裏立馬打印出了'resolve'。遇到setTimeout2後,一樣新建了一個宏任務隊列,其中的函數被分發到了這個新的宏任務隊列中,then方法中的操做被分發到了微任務隊列中等待
  • 代碼繼續往下,遇到'setTimeout3'後再次新建了一個新的宏任務隊列
  • 'end'被當即執行。此時有三個宏任務隊列,一個微任務隊列
  • 微任務隊列中的操做被執行,也就是打印出了‘then’,此時,第一輪的事件循環結束。
  • 第一輪的事件循環結束,開始下一輪的事件循環,依次執行每一個宏任務隊列中的內容,咱們這裏宏任務隊列中的函數比較簡單,都是console操做,因此並無再分發新的任務隊列,可是因爲第二個setTimeout設定了200毫秒的延時,因此‘setTimeout2’被最後打印。

說到這裏,你基本上對事件循環有個大體的瞭解了。以前有個同窗問過我一個問題,點擊輪播圖下一頁,可是頁面沒有反應,代碼是這樣的:線程


這個函數是點擊下一頁的按鈕後輪播圖轉動,他在getNextPhoto函數中調接口獲取了下個頁面的數據,goToPage函數裏是讓輪播圖切換的操做。相信若是你讀懂了這篇文章,就會知道問題出在了哪裏。顯然獲取數據ajax是個異步操做,他被分發到了事件隊列中等待執行,因此還沒等數據回來,翻頁的操做已經開始執行,因爲沒有數據,並無按預期效果顯示。解決方法就是在getNextPhoto函數裏調接口拿到數據以後,再通知去執行goToPage操做,問題就解決了。code

做爲一個前端菜鳥,但願獲得各位大神的批評指正!server

相關文章
相關標籤/搜索