本文已發佈在西瓜君的我的博客,原文傳送門javascript
寫這一篇的時候,西瓜君查閱了不少資料和文章,可是至關多的文章寫的都很簡單,甚至互相之間有矛盾,這讓我很困擾;同時也讓我堅決了要寫出一篇好的關於JS異步、單線程、事件循環的文章,下面,讓咱們一塊兒來學習本文吧,衝鴨~~html
### 1. 什麼是單線程html5
//栗子1 console.log(1) console.log(2) console.log(3) //輸出順序 1 2 3
單線程即同一時間只作一件事java
爲了利用多核CPU的計算能力,HTML5提出Web Worker標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM。因此,這個新標準並無改變JavaScript單線程的本質。node
同步任務:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務web
異步:不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行chrome
//異步的栗子 console.log(1) setTimeout(()=>{ console.log(2) },100) console.log(3) //輸出順序 1 3 2
若是在JS代碼執行過程當中,某段代碼執行太久,後面的代碼遲遲不能執行,產生阻塞(即卡死),會影響用戶體驗。api
JS 實現異步時經過 事件循環(Event Loop),下面咱們來了解一下瀏覽器
先理解幾個概念多線程
當一個JS文件第一次執行的時候,js引擎會 解析這段代碼,並將其中的同步代碼 按照執行順序加入執行棧中,而後從頭開始執行。若是當前執行的是一個方法,那麼js會向執行棧中添加這個方法的執行環境,而後進入這個執行環境繼續執行其中的代碼。當這個執行環境中的代碼 執行完畢並返回結果後,js會退出這個執行環境並把這個執行環境銷燬,回到上一個方法的執行環境。這個過程反覆進行,直到執行棧中的代碼所有執行完畢。
舉個栗子:
//Event loop //(1) console.log(1) //(2) setTimeout(()=>{ console.log(2) },100) //(3) console.log(3)
因此結果是 1 3 2
注:setTimeout/Promise等咱們稱之爲任務源。而進入任務隊列的是他們指定的回調
上面的循環只是一個宏觀的表述,實際上異步任務之間也是有不一樣的,分爲 宏任務(macro task) 與 微任務(micro task),最新的標準中,他們被稱爲 task與 jobs
下面咱們再詳細講解一下執行過程
執行棧在執行的時候,會把宏任務放在一個宏任務的任務隊列,把微任務放在一個微任務的任務隊列,在當前執行棧爲空的時候,主線程會 查看微任務隊列是否有事件存在。若是微任務隊列不存在,那麼會去宏任務隊列中 取出一個任務 加入當前執行棧;若是微任務隊列存在,則會依次執行微任務隊列中的全部任務,直到微任務隊列爲空(一樣,是吧隊列中的事件加到執行棧執行),而後去宏任務隊列中取出最前面的一個事件加入當前執行棧...如此反覆,進入循環。
注:
舉個栗子:
//Event loop //(1) setTimeout(()=>{ console.log(1) },100) //(2) setTimeout(()=>{ console.log(2) },100) //(3) new Promise(function(resolve,reject){ //(4) console.log(3) resolve(4) }).then(function(val){ //(5) console.log(val); }) //(6) new Promise(function(resolve,reject){ //(7) console.log(5) resolve(6) }).then(function(val){ //(8) console.log(val); }) //(9) console.log(7) //(10) setTimeout(()=>{ console.log(8) },50)
*上面的代碼在node和chrome環境的正確打印順序是 3 5 7 4 6 8 1 2
下面分析一下執行過程:
注:由於渲染也是宏任務,須要在一次執行棧執行完後纔會執行渲染,因此若是執行棧中同時有幾個同步的改變同一個樣式的代碼,在渲染時只會渲染最後一個
寫到這裏,仍然以爲還有不少知識點沒有寫出來,可是想寫又不知道從哪裏入手。因而決定今天就寫到這裏,往後再作補充。
到這篇,JS三座大山系列就暫時完結了,在這其中本身也學到了不少,但願能繼續輸出一些有意義的東西,加油,西瓜君~~
參考文章:
https://www.jianshu.com/p/12b9f73c5a4f
http://www.javashuo.com/article/p-fliavhij-eb.html
若有錯誤,請斧正
以上