js運行機制(事件循環 Event Loop)

在瞭解javascript運行機制前 我們需要了解一下以下幾點:

  • javascript是多線程還是單線程?

  • 一個簡單的測試

  • javascript中的 同步任務與異步任務

  • javascript中的 執行棧

  • javascript中的回調函數和事件

  • Javascript中的任務隊列

  • javascript中的Event Loop

javascript是多線程還是單線程?

JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能做一件事。

一個簡單的測試,思考一下 以下代碼 的運行結果

function syncAndAsync() {
    console.log("1") //步驟1
    setTimeout(() => {//步驟3
      console.log("2")
    }, 1000);
    console.log("3")//步驟2
  }

運行結果:1,3,2
爲什麼 是這樣的結果呢?

如果把步驟2的時間改爲0秒 結果會如何呢?

請讀完js的運行機制後 ,答案就很明瞭了。

javascript中的同步任務與異步任務

因爲javascript是單線程的 ,所以 javascript 把運行的任務,設計了兩種 同步任務和異步任務

同步任務指的是:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;

異步任務指的是:不進入主線程、被主線程掛起的任務,只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。當主線程 的所有同步任務執行完後,查看該任務隊列 的事件,對應的任務 結束等待狀態,進入執行棧,開始執行。

javascript中的 執行棧

所有同步任務都是在主線程上執行的,這些同步任務在主線程上的執行,這就是執行棧。

javascript中的回調函數

回調函數,就是那些會被主線程掛起來的任務。異步任務必須指定回調函數,當主線程開始執行異步任務,就是執行對應的回調函數。

Javascript中的任務隊列

"任務隊列"是一個事件的隊列(也可以理解成消息的隊列),隊列中對應的任務有了結果(比如讀取文件(io操作),請求遠程數據等等),就在"任務隊列"中添加一個事件,表示相關的異步任務可以進入"執行棧"了。主線程讀取"任務隊列",就是讀取裏面有那些事件。

"任務隊列"中的事件,除了IO設備的事件以外,還包括一些用戶產生的事件(比如鼠標點擊、頁面滾動等等)。只要指定過回調函數,這些事件發生時就會進入"任務隊列",等待主線程讀取。

javascript中的Event Loop

主線程先執行同步任務,也就是執行棧中的 任務,當執行完所有的執行棧中的任務後 ,從"任務隊列"中讀取事件,然後執行對應可執行狀態的異步任務(回調)。這個過程是不斷循環的,所以整個的這種運行機制又稱爲Event Loop(事件循環)。

異步執行的運行機制步驟如下:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章