淺談JavaScript運行機制


淺談JavaScript運行機制

​ 想要了解一門語言,最好的辦法就是了解它的運行機制。掌握了運行機制,能夠讓我們在開發中少走許多彎路,寫出高質量的代碼。本文簡單介紹什么是JavaScript的運行機制,給剛剛接觸JavaScript的小白一個初步的了解,為將來打好基礎。

一、JavaScript 代碼運行的兩個階段:

1、預解析---把所有的函數定義提前,所有的變量聲明提前,變量的賦值不提前

2、執行---從上到下執行(按照js運行機制)

二、JavaScript運行機制的特點

1.JavaScript是一門單線程語言

2.事件循環(Event Loop)

三、單線程

1.什么是單線程

	JavaScript的一個語言特性(也是這門語言的核心)就是單線程,也就是說,同一個時間只能做一件事,當有多個任務時,只能按照順序上一個任務完成了再執行下一個。上一個任務未完成則會一直等待。
	JavaScript所有的多線程都是模擬出來的,本質還是單線程

2.為什么JavaScript是單線程

	JavaScript的單線程而不是多線程,主要與它的用途有關。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM(文檔對象模型)和BOM(瀏覽器對象模型)。而多線程需要共享資源,多線程編程經常面臨鎖、狀態同步等問題。這決定了JavaScript只能是單線程。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為准?會帶來許多問題
	所以,為了避免復雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特征,將來也不會改變。
	

3.單線程帶來的問題及解決方法

	單線程意味着同一時間只能進行一件事情,前面的事情結束才能執行后面的事件.當碰到需要時間的IO事件的時候問題就來了,必須等到這些結束后才往下進行,但這時CPU是閑着的.這樣浪費了很多計算機的性能
	JavaScript語言的設計者意識到,這時主線程完全可以不管IO設備,掛起處於等待中的任務,先運行排在后面的任務。等到IO設備返回了結果,再回過頭,把掛起的任務繼續執行下去。將所有任務分成兩種,一種是同步任務(synchronous),另一種是異步任務(asynchronous)
	為了提高CPU的利用率,HTML5提出Web Worker標准,允許JavaScript腳本創建多個線程,但是子線程完全受主線程控制,且不得操作DOM。所以這個標准並沒有改變JavaScript單線程的本質

四、同步和異步

同步:
	在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行后一個任務;
異步:
	不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務可以執行了,該任務才會進入主線程執行

例題:

console.log(1);
setTimeout(function(){
	console.log(2);
},0);
console.log(3);
//1 3 2 ---不是按照123的先后順序輸出。因為延時器觸發了異步
console.log("A");
while(true){ }
console.log("B");
//A ---遇到死循環,程序卡在死循環。后面的語句執不了
console.log("A");
setTimeout(function(){
	console.log("B");
},0);
while(true){}
//A----只輸出A,延時器異步等主線程結束后執行,主線程遇到死循環,后面的不再執行

五、理解Event Loop(事件循環)

異步執行運行機制如下:理解任務隊列(消息隊列)

(1)所有同步任務都在主線程上執行,形成一個執行棧(execution context stack)
(2)主線程之外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件
(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務隊列",看看里面有哪些事件。那些對應的異步任務,於是結束等待狀態,進入執行棧,開始執行
(4)主線程不斷重復上面的第三步

JavaScript的運行機制:主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為Event Loop(事件循環)。只要主線程空了,就會去讀取"任務隊列"。這個過程會循環反復。以下這張圖可以很好說明這點。

六、哪些語句會放入異步任務隊列

一般來說,有以下四種會放入異步任務隊列:

  1. setTimeout(延時器)和setInterval(定時器)
  2. DOM事件
  3. ES6中的Promise
  4. Ajax異步請求


免責聲明!

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



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