js執行機制

来源:https://www.cnblogs.com/jiaobaba/archive/2019/11/27/11943682.html
-Advertisement-
Play Games

js是單線程的,為什麼可以執行非同步操作呢? 這歸結與瀏覽器(js的宿主環境)通過某種方式使得js具備了非同步的屬性。 區分進程和線程: 進程:正在運行中的應用程式。每個進程都自己獨立的記憶體空間。例如:打開的瀏覽器就是一個進程。 線程:進程的子集,是獨立的。線程在共用的記憶體空間中運行。 瀏覽器是多進程的 ...


js是單線程的,為什麼可以執行非同步操作呢?

這歸結與瀏覽器(js的宿主環境)通過某種方式使得js具備了非同步的屬性。

 

 

區分進程和線程:

 

進程:正在運行中的應用程式。每個進程都自己獨立的記憶體空間。例如:打開的瀏覽器就是一個進程。

線程:進程的子集,是獨立的。線程在共用的記憶體空間中運行。

 

 

瀏覽器是多進程的。如下圖:

 

 

 並且每打開一個頁面就創建了一個獨立的進程。進程內有自己的多線程。如果瀏覽器是單進程的,那麼某個頁面崩了,就會影響整個瀏覽器。

 

瀏覽器有哪些進程:

1.Browser(瀏覽器):瀏覽器的主進程(負責協調,主控)只有一個,作用有:
  • 負責瀏覽器界面顯示,與用戶交互。如前進,後退等
  • 負責各個頁面的管理,創建和銷毀其他進程
  • 將Renderer(渲染器)進程得到的記憶體中的Bitmap,繪製到用戶界面上
  • 網路資源的管理,下載等
2.第三方插件進程:每種類型的插件對應一個進程,僅當使用該插件時才創建 3.GPU進程:最多一個,用於3D繪製等 4.瀏覽器渲染進程(瀏覽器內核)(Renderer(渲染器),內部是多線程的)預設每個Tab頁面一個進程,互不影響。主要作用 :頁面渲染,腳本執行,事件處理等   瀏覽器渲染進程(瀏覽器內核)包含的線程: 1. GUI渲染線程 • 負責渲染瀏覽器界面,解析HTML,CSS,構建DOM樹和RenderObject樹,佈局和繪製等。 • 當界面需要重繪(Repaint)或由於某種操作引發迴流(reflow)時,該線程就會執行 • 註意,GUI渲染線程與JS引擎線程是互斥的,當JS引擎執行時GUI線程會被掛起(相當於被凍結了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。 2. JS引擎線程( “JavaScript 引擎”通常被稱作一種 虛擬機。也稱為JS內核,負責處理Javascript腳本程式。(例如V8引擎) • JS引擎線程負責解析Javascript腳本,運行代碼。 • JS引擎一直等待著任務隊列中任務的到來,然後加以處理,一個Tab頁(renderer進程)中無論什麼時候都只有一個JS線程在運行JS程式 • 同樣註意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染載入阻塞。 3. 事件觸發線程 • 歸屬於瀏覽器而不是JS引擎,用來控制事件迴圈(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協助) • 當JS引擎執行代碼塊如setTimeOut時(也可來自瀏覽器內核的其他線程,如滑鼠點擊、AJAX非同步請求等),會將對應任務添加到事件線程中 • 當對應的事件符合觸發條件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理 • 註意,由於JS的單線程關係,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閑時才會去執行) 4. 定時觸發器線程 • 傳說中的setInterval與setTimeout所線上程 • 瀏覽器定時計數器並不是由JavaScript引擎計數的,(因為JavaScript引擎是單線程的, 如果處於阻塞線程狀態就會影響記計時的準確) • 因此通過單獨線程來計時並觸發定時(計時完畢後,添加到事件隊列中,等待JS引擎空閑後執行) • 註意,W3C在HTML標準中規定,規定要求setTimeout中低於4ms的時間間隔算為4ms。 5. 非同步http請求線程 • 在XMLHttpRequest在連接後是通過瀏覽器新開一個線程請求 • 將檢測到狀態變更時,如果設置有回調函數,非同步線程就產生狀態變更事件,將這個回調再放入事件隊列中。再由JavaScript引擎執行。

 

GUI渲染線程與JS引擎線程互斥: 由於JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JS線程和UI線程同時運行),那麼渲染線程前後獲得的元素數據就可能不一致了。因此為了防止渲染出現不可預期的結果,瀏覽器設置GUI渲染線程與JS引擎為互斥的關係,當JS引擎執行時GUI線程會被掛起,GUI更新則會被保存在一個隊列中等到JS引擎線程空閑時立即被執行。     js執行機制:js是單線程的,每當執行函數就把函數推入棧中,但有非同步的操作就讓瀏覽器的線程(webAPI)去處理,處理完放到任務隊列里,當主線程(執行棧)執行完畢時,如果任務隊列里有任務,就執行。  

 

 這也就是為什麼下麵代碼會先輸出b,然後是a的原因。settimeout的函數會放到任務隊列中,而console.log('b')是主線程。

     setTimeout(() => {
            console.log('a');
        }, 0);
        console.log('b'); 

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • CSS中的選擇器優先順序與!important權重使用 選擇器要高於標簽選擇器。 選擇器要高於 選擇器。 標簽選擇器是優先順序最低的選擇器。 的屬性它的權重值優先順序最高的,大於所有的選擇器。 標簽選擇器和.class選擇器 讓我們進入標簽選擇器和 選擇器誰的優先順序高實踐,實踐內容如:將 頁面中的 標簽設 ...
  • CSS樣式繼承介紹 外層元素身上的樣式會被內層元素所繼承。 當內層元素身上的樣式與外層的元素身上的樣式相同時內層元素樣式會覆蓋外層元素樣式。 並不是所有的樣式都能夠繼承,只有文本與字體樣式屬性才能夠被繼承,其餘的樣式屬性不可以被繼承。 CSS樣式繼承實踐 外層元素身上的樣式會被內層元素所繼承,這句話 ...
  • HTML DOM 學習 By: Mirror王宇陽 E mail:[email protected] 博客主頁:https://www.cnblogs.com/wangyuyang1016/ DOM 文檔對象模型 DOM簡單來說就是文檔對象模型,當一個HTML頁面被載入就會創建HTML頁面的DOM ...
  • DOM遍歷 parent()方法返回所選元素的直接父元素。(parent() 只能遍歷單個級別的 DOM樹) parents()方法獲取所選元素的所有祖先 children()所選元素的所有直接子元素 siblings()所有兄弟元素 next()/nextAll()下一個兄弟元素/下麵所有兄弟元素 ...
  • // 線性漸變,多用於折線柱形圖,前四個參數分別是 x0, y0, x2, y2, 範圍從 0 - 1,相當於在圖形包圍盒中的百分比,如果 globalCoord 為 `true`,則該四個值是絕對的像素位置 color: { type: 'linear', x: 0, // 左上角x y: 0, ...
  • 摘要 由於需要用到彈出層但是懶得造輪子所以使用vant 介紹 使用的node包管理器為yarn vue-cli版本4 rem計算方式為index.html的js腳本計算 安裝vant yarn add vant 配置 安裝babel-plugin-import實現按需載入 yarn add babe ...
  • let option = { backgroundColor: '#1a4377', animationDurationUpdate: 1500, // 動畫更新變化時間 animationEasingUpdate: 'quinticInOut', // 動畫緩動效果 series: [ { typ ...
  • HTML: click <a>,add active class, and remove other a's active class: a is an array, as: and a[1]: value of a[1]'s id attribute: $(a[1]).attr['id'] , w ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...