js 的單線程與異步

js的單線程

從咱們第一天接觸js的時候咱們就知道js是單線程的,且js是異步的,首先來看一下基本概念javascript

什麼是線程

線程是操做系統可以進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運做單位。(百度百科)css

舉個最簡單的例子 , 在咱們電腦的任務管理器中你打開一個應用程序的時候 就會多一個進程,他表明了cpu能處理的單個任務。html

線程是進程下的執行者,一個進程至少會開啓一個線程(主線程),也能夠開啓多個線程,好比你打開了一個vscode編輯器,裏邊你能作的操做會有不少好比cmd node 等等前端

瀏覽器的進程

js是運行在瀏覽器的,是由js引擎解析和執行的,那麼咱們先了解一下瀏覽器都有哪些線程
首先要說明的是 瀏覽器是多線程的java

  • Browser進程:瀏覽器的主進程node

  • 第三方插件進程web

  • GPU進程ajax

  • 瀏覽器渲染進程數據庫

對於前端來說這些進程中最重要的是瀏覽器渲染進程,也被稱之爲是瀏覽器內核,由於咱們的頁面渲染,事件等等都在這個進程中進行的promise

瀏覽器的渲染進程裏邊有一些常駐的線程好比說

GUI渲染線程
  • 負責解析html css 構建dom樹 編譯 RenderObject樹,計算佈局渲染等等
  • 在頁面重回或者dom迴流的時候這個線程就會被執行
  • 頁面在第一次渲染的時候確定會觸發這個線程
Js引擎線程
  • 主要負責處理javascript的腳本
  • 也稱之爲js內核,一個tab頁中只有一個js線程在運行js程序

須要注意的是Gui渲染線程和js引擎線程是衝突的,他們不能同時執行

因此說若是咱們頁面在一開始js文件須要計算或者操做的時間比較長的時候,會出現大段時間的白屏,
由於js引擎在執行的時候會使頁面渲染堵塞,若是dom發生更新的時候,gui更新會被存在一個隊列裏邊,等到js引擎空閒的時候纔會被執行

一個tab頁裏邊不管如何都只有一個js線程,就算是後來的webworker ,他也是隻屬於js引擎的一個子類,而且它不能操做dom

事件觸發線程
  • 經常使用的事件有不少好比點擊事件 ajax請求事件等等他們會在對應的條件觸發的時候被添加到事件線程中
  • 這些事件會在js引擎空閒的時候去執行
定時觸發器線程
  • 定時器與計時器的線程,在知足條件以後會被添加到事件隊列裏邊,等待js引擎空閒的時候去執行
http請求
  • 在發送http請求的時候,這個線程會被執行
  • 再有回調函數的時候,這個線程會把回調的事件放入到事件隊列中去,等待js引擎執行

忽然以爲js引擎好累,什麼都是要他去作,爲何不設計成多線程,從網上其餘地方看了的答案,大同小異,講的是多線程操做dom有可能會同時操做一個dom發生錯誤云云

說完了上邊的一些概念,你也應該大致的瞭解了js的單線程這個問題
下邊從js引擎的一些運行機制說一說js的異步

剛纔已經講了,瀏覽器中不只有js引擎線程還有其餘,異步的話主要會用到事件觸發線程和定是觸發器線程的概念

在js中氛圍同步任務和異步任務 ,全部的同步任務都會在主線程上執行,造成一個執行棧(先進後出)
在主線程以外還有一個異步的事件隊列
在執行棧執行完畢以後,也就是同步任務執行完畢以後,js引擎線程就會去輪詢事件隊列,看有沒有須要執行的事件,有的話就會執行事件隊列的事件

我記得我最開始的時候使用ajax 或者數據庫查詢的時候遇到過這麼一個狀況,在作完操做以後就天真的認爲能夠用返回的值,結果當時我被異步搞得裏焦外嫩,甚至我覺得在發送完請求以後多作一些操做等一會請求,請求值就會返回來,結果。。。

其實否則, 在同一個事件循環內部,不管作多少操做,你的異步操做只會在執行棧執行完畢以後纔會被執行

同時異步也是有優先級的,在事件循環裏邊js的任務類型分爲兩種

  • 宏任務
  • 微任務

宏任務就是說執行棧裏的每個被執行的代碼就是一個宏任務,包括一個事件產生的回調執行
宏任務會在執行完畢一段代碼以後先對dom進行一次渲染,而後再執行下一個宏任務

微任務是再宏任務執行完畢以後當即執行的,他在dom從新渲染以前,
因此微任務的相應速度比宏任務是要快的

像 定時器,延時器 主代碼塊等等就是一個宏任務,promise nextTick等就是微任務
正常在延時器打印和在promise裏邊打印,promise的打印是會比延時器的先打印的

因此總結一下js的運行機制是

  • 執行棧執行宏任務
  • 執行棧沒有任務就去輪詢事件隊列
  • 若是執行期間遇到微任務,就添加到微任務隊列
  • 一個宏任務執行完畢後會當即執行當前微任務隊列的任務
  • 宏任務執行完畢後開始渲染
  • 而後開啓下一輪宏任務

以上有說的不對或者不足之處,請批評指正

相關文章
相關標籤/搜索