JS 單線程


js單線程阻塞實例
setTimeout(function () { while (true) { } }, 1000);
setTimeout(function () { alert('end 2'); }, 2000);
setTimeout(function () { alert('end 1'); }, 100);
alert('end');
結果是彈出’end’、’end 1’,然后瀏覽器假死,就是不彈出‘end 2’。

 

js單線程重點:
JS 是單線程的,但是卻能執行異步任務,
這主要是因為 JS 中存在事件循環(Event Loop)和任務隊列(Task Queue)。


事件循環:
JS 會創建一個類似於 while (true) 的循環,
每執行一次循環體的過程稱之為 Tick。
每次 Tick 的過程就是查看是否有待處理事件,
如果有則取出相關事件及回調函數放入執行棧中由主線程執行。
待處理的事件會存儲在一個任務隊列中,
也就是每次 Tick 會查看任務隊列中是否有需要執行的任務。


任務隊列:
異步操作會將相關回調添加到任務隊列中。
而不同的異步操作添加到任務隊列的時機也不同,如 onclick, setTimeout, ajax 處理的方式都不同,
這些異步操作是由瀏覽器內核的 webcore 來執行的。
onclick 由瀏覽器內核的 DOM Binding 模塊來處理,
當事件觸發的時候,回調函數會立即添加到任務隊列中。
setTimeout 會由瀏覽器內核的 timer 模塊來進行延時處理,
當時間到達的時候,才會將回調函數添加到任務隊列中。
ajax 則會由瀏覽器內核的 network 模塊來處理,
在網絡請求完成返回之后,才將回調添加到任務隊列中。


主線程:
JS 只有一個線程,稱之為主線程。
而事件循環是主線程中執行棧里的代碼執行完畢之后,才開始執行的。
所以,主線程中要執行的代碼時間過長,會阻塞事件循環的執行,也就會阻塞異步操作的執行。
只有當主線程中執行棧為空的時候(即同步代碼執行完后),才會進行事件循環來觀察要執行的事件回調,
當事件循環檢測到任務隊列中有事件就取出相關回調放入執行棧中由主線程執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM