javascript
JS 单线程
js單線程阻塞實例
setTimeout(function () { while (true) { } }, 1000);
setTimeout(function () { alert('end 2'); }, 2000);
setTimeout(function () { alert('end 1'); }, 100);
alert('end');
結(jié)果是彈出’end’、’end 1’,然后瀏覽器假死,就是不彈出‘end 2’。
?
js單線程重點:
JS 是單線程的,但是卻能執(zhí)行異步任務,
這主要是因為 JS 中存在事件循環(huán)(Event Loop)和任務隊列(Task Queue)。
事件循環(huán):
JS 會創(chuàng)建一個類似于 while (true) 的循環(huán),
每執(zhí)行一次循環(huán)體的過程稱之為 Tick。
每次 Tick 的過程就是查看是否有待處理事件,
如果有則取出相關事件及回調(diào)函數(shù)放入執(zhí)行棧中由主線程執(zhí)行。
待處理的事件會存儲在一個任務隊列中,
也就是每次 Tick 會查看任務隊列中是否有需要執(zhí)行的任務。
任務隊列:
異步操作會將相關回調(diào)添加到任務隊列中。
而不同的異步操作添加到任務隊列的時機也不同,如 onclick, setTimeout, ajax 處理的方式都不同,
這些異步操作是由瀏覽器內(nèi)核的 webcore 來執(zhí)行的。
onclick 由瀏覽器內(nèi)核的 DOM Binding 模塊來處理,
當事件觸發(fā)的時候,回調(diào)函數(shù)會立即添加到任務隊列中。
setTimeout 會由瀏覽器內(nèi)核的 timer 模塊來進行延時處理,
當時間到達的時候,才會將回調(diào)函數(shù)添加到任務隊列中。
ajax 則會由瀏覽器內(nèi)核的 network 模塊來處理,
在網(wǎng)絡請求完成返回之后,才將回調(diào)添加到任務隊列中。
主線程:
JS 只有一個線程,稱之為主線程。
而事件循環(huán)是主線程中執(zhí)行棧里的代碼執(zhí)行完畢之后,才開始執(zhí)行的。
所以,主線程中要執(zhí)行的代碼時間過長,會阻塞事件循環(huán)的執(zhí)行,也就會阻塞異步操作的執(zhí)行。
只有當主線程中執(zhí)行棧為空的時候(即同步代碼執(zhí)行完后),才會進行事件循環(huán)來觀察要執(zhí)行的事件回調(diào),
當事件循環(huán)檢測到任務隊列中有事件就取出相關回調(diào)放入執(zhí)行棧中由主線程執(zhí)行。
轉(zhuǎn)載于:https://www.cnblogs.com/justSmile2/p/10764297.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結(jié)
- 上一篇: 第二单元作业——电梯模拟总结
- 下一篇: JavaScript 中最重要的保留