Event Loop

javascript 運行時

  • 堆:記錄了內存的分配
  • 調用棧:是棧幀這類東西所在的地方

setTimeout或者DOM,HTTP請求這些東西並不存在於V8引擎中 那咱們如何進行異步編程呢?javascript

  • 上圖中包含了V8運行環境
  • 而後是瀏覽器提供的其它部分WebAPIs(DOM,AJAX,setTimeout)
  • 再而後就是事件循環event loop 和 回調隊列 call back queue

單線程

  • javascript是一個單線程的編程語言
  • 單線程的運行環境,它有且只有一個調用棧,它每次只可以作一件事情

call stack 調用棧

什麼是調用棧java

cal stack是記錄當前程序所在位置的數據結構編程

  • 若是當前進入了某個函數,v8就建立一個棧幀壓入棧中
  • 若是當前離開了某個函數,該棧幀就會被彈出棧外

你能夠藉助以下動圖理解call stack瀏覽器

當咱們在Chrome的控制檯上運行以下代碼時,會拋出一個異常,它將整個棧樹都打印了出來數據結構

錯誤是從foo開始,到bar,到baz,再到匿名函數,也就是上圖中的main函數異步

內存泄露

若是咱們有一個調用自身的函數foo,那麼會發生什麼呢?編程語言

阻塞

沒有什麼嚴格意義上的阻塞,阻塞僅僅指的是代碼運行很慢,好比說異步編程

  • console.log不慢,可是遍歷從1到10億很慢
  • http請求很慢
  • 加載圖片很慢

反正在調用棧裏表現很慢的東西都叫阻塞函數

同步任務和異步任務

javascript程序中任務能夠分爲兩類oop

  • 1 同步任務
  • 2 異步任務

同步任務會依次進入call stack調用棧中執

異步任務會被v8引擎聽任務隊列中,只有當同步任務所有執行完畢,異步任務纔會從隊列首部至尾部依次進入調用棧執行

任務隊列和事件循環

V8引擎提供了兩個東西

  • 1一個正在運行的主線程
  • 2 task queue 任務隊列(用於存放程序中的異步任務)
    • 每個異步任務都有一個爲了處理這個異步任務相關聯的函數
  • 1 主線程會去執行全部的同步任務。
  • 2 等到同步任務所有執行完,就會去看任務隊列裏面的異步任務。
  • 3 若是知足條件,那麼異步任務就從新進入主線程開始執行,這時它就變成同步任務了。
  • 4 等到執行完,下一個異步任務再進入主線程開始執行。一旦任務隊列清空,程序就結束執行

經過下面動圖加深理解

事件循環

異步任務的寫法一般是回調函。一旦異步任務從新進入主線程,就會執行對應的回調函數。若是一個異步任務沒有回調函數,就不會進入任務隊列,也就是說,不會從新進入主線程,由於沒有用回調函數指定下一步的操做。

javaScript 引擎怎麼知道異步任務有沒有結果,能不能進入主線程呢?答案就是v8引擎在不停地檢查,一遍又一遍,只要同步任務執行完了,引擎就會去檢查那些掛起來的異步任務,是否是能夠進入主線程了。這種循環檢查的機制,就叫作事件循環(Event Loop)

總結

V8引擎主要作了哪些事情

  • 1 按照代碼順序依次執行任務
  • 2 主線程遇到同步任務就放入call stack中執行,遇到異步任務就暫時掛起,
  • 3 執行同步任務的同時,事件循環(event loop)定時查看異步任務的結果,符合條件的異步任務放入到任務隊列中
  • 4 程序中全部同步任務執行完畢後,主線程按照隊列先進先出的特色,老是從最早進入隊列的一個任務開始處理
  • 5 每個任務都有一個與之相關的處理函數,只有當這個函數徹底執行完後,才能處理下一個任務
  • 6 當全部異步任務執行完畢以後,程序結束
相關文章
相關標籤/搜索