瀏覽器
做爲瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操做DOM。這決定了它只能是單線程,不然會帶來很複雜的同步問題。好比,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時瀏覽器應該以哪一個線程爲準?網絡
單線程就意味着,全部任務須要排隊,前一個任務結束,纔會執行後一個任務。若是前一個任務耗時很長,後一個任務就不得不一直等着異步
若是排隊是由於計算量大,CPU忙不過來,倒也算了,可是不少時候CPU是閒着的,由於IO設備(輸入輸出設備)很慢(好比Ajax操做從網絡讀取數據),不得不等着結果出來,再往下執行。async
JavaScript語言的設計者意識到,這時主線程徹底能夠無論IO設備,掛起處於等待中的任務,先運行排在後面的任務。等到IO設備返回告終果,再回過頭,把掛起的任務繼續執行下去。函數
同步任務(synchronous):在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;oop
異步任務(asynchronous):不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。spa
主線程運行的時候,產生堆(heap)和棧(stack),棧中的代碼調用各類外部API,它們在"任務隊列"中加入各類事件(click,load,done)。只要棧中的代碼執行完畢,主線程就會去讀取"任務隊列",依次執行那些事件所對應的回調函數。線程
console.log(1); console.log(2); setTimeout(function(){ console.log(3); }) setTimeout(function(){ console.log(4); }) console.log(5);
輸出:1 2 5 3 4設計
首先執行了棧裏的代碼1 2 5。 settimeout會被放在隊列裏,當棧執行完了以後,任務隊列裏的事件會添加到棧裏依次執行,獲得 3 4code
沒搞懂的地方:這個流程是js引擎實現的仍是瀏覽器底層實現的?究竟是任務隊列通知仍是執行棧空了詢問?b站英文視頻有空從新看一下!