Javascript是一種單線程開發語言。理解Javascript的運行機制是平常編碼必需要掌握的技能。
JavaScript的主要用途是與用戶交互,以及操做DOM。這決定了它只能是單線程,不然會帶來很複雜的同步問題。git
單線程就意味着容易發生線程等待資源,cpu空閒,而其餘任務一直等待的問題。github
爲了協調事件、用戶交互、腳本、UI 渲染和網絡處理等行爲,防止主線程阻塞。因而Javascript設計者將全部任務分爲兩種,一種是同步任務,一種是異步任務promise
同步任務指的是,在主線程
上排隊執行的任務瀏覽器
同步任務都在主線程上執行,造成一個執行棧
網絡
異步任務指的是,不進入主線程,而進入任務隊列
的任務。數據結構
執行棧中的全部同步任務執行完畢
,系統就會讀取「任務隊列」。"主線程"從"任務隊列"中讀取事件,這個過程是循環不斷的,因此整個的這種運行機制又稱爲Event Loop(事件循環)。多線程
根據規範:每一個任務都有一個任務源(task source),源自同一個任務源的 task 必須放到同一個任務隊列,從不一樣源來的則被添加到不一樣隊列,因此有了宏任務(macro)task和微任務(micro)task。異步
瀏覽器爲了可以使得JS內部(macro)task與DOM任務可以有序的執行,會在一個task執行結束後,在下一個(macro)task 執行開始前,對頁面進行從新渲染,函數
每次執行完一個宏任務以後,會去檢查是否存在微任務;若是有,則執行微任務直至清空微任務隊列,若是在微任務執行期間微任務隊列加入了新的微任務,會將新的微任務加入隊列尾部,以後也會被執行。oop
根據上述總結流程爲:
附(宏/微任務清單):
目前宏任務和微任務在各瀏覽器執行都有差別,最後提議promise爲微任務
setTimeout(function(){ console.log('1'); }); new Promise(function(resolve){ console.log('2'); resolve(); }).then(function(){ console.log('3'); }); console.log('4');
以上案例會輸出 2 4 3 1
結果解析:
JavaScript執行主線程任務:輸出 2 4
輸入 3
輸出 1
持續更新中 來Github 點顆⭐吧