瀏覽器(chrome)進程機制:
瀏覽器作爲一個軟件,大家有沒有好奇瀏覽器是多進程的還是多線程的?每打開一個瀏覽器頁面代表着是一個線程還是一個進程呢?
其實瀏覽器是一個多進程軟件,從開發的角度來說,相對安全的,多線程意味着大家都在'一條船上',你打開蘋果的官網和三星的官網,蘋果官網的頁面崩潰了,三星的頁面也要和你崩潰嗎?無論開發者如何做多線程隔離,線程安全等等操作,整體效果沒有多進程來的安全和穩定的。一般來說一個頁面是一個進程,某些瀏覽器會做優化例如你打開同一個網址。
下面我以chrome瀏覽器來分析其運行機制:
首先我們打開chrome的進程管理器,打開瀏覽器,按下shift+esc即可,或者如圖所示More Tools->Task Manager
就出現這個Task Managerc窗口了
browser進程:瀏覽器的主進程,負責界面的顯示,用戶交互,子進程的管理,提供存儲等功能
GPU Process:GPU進程,負責繪製 repaint 重繪後的 UI 界面
Utility Network:網絡進程,負責頁面網絡資源的加載
插件進程:有插件會顯示插件進程
render進程:內核進程,前端工程師開發和關注的界面,我們用戶開發的進程就是在裏面跑的
JavaScript 運行機制:
1.JavaScript是單線程的語言
原因:這樣不僅高效率還安全。當你使用js對DOM,一個進行增加節點操作,另一個進行刪除節點的操作。多線程的話會使瀏覽器的效率降低。多線程必然會引入的鎖,信號量的一類操作,大大增加了複雜性。而瀏覽器是最貼近用戶體驗的一種軟件,用戶需要的是快!快!簡單!簡單!JavaScript設置成單線程是符合工程應用的
延伸:我們需要了解的是進程,線程,或者纖程(協程),這些都是基於操作系統的概念,不是某個語言的特點。在沒有操作系統的下的編程是沒有進程,線程這個說法的。例如C語言,你在Windows或者linux下的編程,有進程,線程這種說法。然而在stm32,c51/c52這種沒有操作系統的環境下編程,是沒有進程,線程這種說法的。
2.任務隊列
單線程就意味着所有事情任務要一個個來,排隊來。JavaScript把這種任務分成兩種了一個是同步任務(synchronous),另一個是異步任務(asynchronous)。同步任務是在主線程上排隊執行的任務,執行完一個任務才能執行下一個任務。異步任務是指不進入主線程,而是進入“任務隊列”,只有“任務隊列”會通知某個異步任務可以執行了才能執行,該任務會進入主線程執行
例子:
<!DOCTYPE html>
<html>
<head>
<script>
console.log(11111)
setTimeout(function(){
console.log(2222)
})
console.log(333)
</script>
</head>
</html>
這裏打印的結果會是:11111 333 2222
因爲setTimeout是異步的,會進入“任務隊列”,等同步任務console執行完了。才通知異步任務
同步任務執行完之前是不會執行異步任務的
例子:
<!DOCTYPE html>
<html>
<head>
<script>
console.log(11111)
setTimeout(function(){
console.log(2222)
})
while(1){}
// console.log(333)
</script>
</head>
</html>
輸出結果是:11111,不會輸出2222的,因爲同步任務while(1)沒有執行完,不會執行異步任務setTimeout的。
同步任務是一個一個執行的,前一個執行完,纔到下一個執行。
<!DOCTYPE html>
<html>
<head>
<script>
console.log(11111)
/*
setTimeout(function(){
console.log(2222)
})
*/
while(1){}
console.log(333)
</script>
</head>
</html>
輸出的結果是:11111,不會輸出333,因爲同步任務while(1)沒有執行完
3.深入理解Event Loop
異步執行的運行機制如下:
(1)所有同步任務會在主線程形成一個執行棧。
(2)主線程之外的任務隊列只要有異步的運行結果,就在任務隊列中放置一個事件
(3)執行棧中的同步任務執行完畢,系統會讀取任務隊列開始執行。
(4)主線程不斷重複上面三個步驟
故JavaScript的運行機制:主線程從任務隊列中不斷循環讀取事件,這種稱之爲事件循環(EventLoop),只要主線程空了就會讀取任務隊列。
參考文章:https://baijiahao.baidu.com/s?id=1615713540466951098&wfr=spider&for=pc
4.哪些屬於異步任務
一般有四種:
1.setTimeout和setInterval
2.DOM事件
3.ES6中的Promise
4.Ajax異步請求
說明即使是異步任務也分優先級,分爲微任務和宏任務,微任務的優先級高於宏任務優選執行
微任務:setTimeout
宏任務:setInterval
再說說JavaScript的運行過程:
1.語法分析,js會檢查你是否會有語法錯誤這種低級錯誤,每個語言都會有這一步
2.預解析:將函數聲明和定義整體提前,就是說在一個域內說不管你函數定義在前面,中間,後面,都會把你的函數整體提升到最前面。將變量的的聲明整體提前,定義不提前。就是說在一個域內說不管你變量定義在前面,中間,後面,都會把你的變量聲明提升到最前面,注意定義不提前。總結:函數定義整體提升,變量定義變量聲明提升
3.找到函數的形參,將形參和實參統一
4.執行---從上到下執行(按照js運行機制)
函數定義整體提升,變量定義變量聲明提升
舉例:
<!DOCTYPE html>
<html>
<head>
<script>
console.log(test)
function test(){
console.log('函數')
}
</script>
</head>
</html>
雖然是在後面定義了函數,但是函數定義整體提升,js會放在前面解析,所以輸出能看到test是個函數,而不是undefined之類的。
<!DOCTYPE html>
<html>
<head>
<script>
console.log('a:'+a)
var a = 10
</script>
</head>
</html>
變量定義,聲明整體提升,所以a輸出的是undefined,就是說a是聲明瞭,卻沒有定義。(若沒有聲明會報錯的,不會輸出undefined)
總結:
js在瀏覽器(chrome)的render進程裏面跑,js是單線程語言,js運行機制有同步任務和異步任務之分