主進程中發生了一個javascript錯誤_知道html5 Web Worker標準嗎?能實現JavaScript的多線程?

js為什么是單線程?

主要是因為最開始javascript是單純的服務于瀏覽器的一種腳步語言(那時候沒有nodejs)。瀏覽器是為了渲染網頁,通過dom與用戶交互,如果一個線程需要給dom執行click事件,而另一個進程要刪除這個dom,這2個動作可能同時進行,也可能先后進行(像java,c#等語言中會引入鎖的概念,這樣會變得異常復雜),那么就會造成很多不可預料的錯誤。

所以,為了避免復雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特征。為了利用多核CPU的計算能力,HTML5提出Web Worker標準,允許JavaScript腳本創建多個線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個新標準并沒有改變JavaScript單線程的本質。

瀏覽器是多線程的

瀏覽器打開一個tab,就會單獨開一個進程,這個進程包含多個線程
主要包含的線程有:

GUI渲染線程
負責渲染瀏覽器界面,解析HTML,CSS,構建DOM樹和RenderObject樹,布局和繪制等。
當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時,該線程就會執行
注意,GUI渲染線程與JS引擎線程是互斥的,當JS引擎執行時GUI線程會被掛起(相當于被凍結了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。JS引擎線程
也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎)
JS引擎線程負責解析Javascript腳本,運行代碼。
JS引擎一直等待著任務隊列中任務的到來,然后加以處理,一個Tab頁(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序
同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞。事件觸發線程
歸屬于瀏覽器而不是JS引擎,用來控制事件循環(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協助)
當JS引擎執行代碼塊如setTimeOut時(也可來自瀏覽器內核的其他線程,如鼠標點擊、AJAX異步請求等),會將對應任務添加到事件線程中
當對應的事件符合觸發條件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理
注意,由于JS的單線程關系,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閑時才會去執行)定時觸發器線程
傳說中的setInterval與setTimeout所在線程
瀏覽器定時計數器并不是由JavaScript引擎計數的,(因為JavaScript引擎是單線程的, 如果處于阻塞線程狀態就會影響記計時的準確)
因此通過單獨線程來計時并觸發定時(計時完畢后,添加到事件隊列中,等待JS引擎空閑后執行)
注意,W3C在HTML標準中規定,規定要求setTimeout中低于4ms的時間間隔算為4ms。異步http請求線程
在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求
將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件隊列中。再由JavaScript引擎執行。
上面列出的線程之間,有一個重要的規則是:GUI渲染線程與JS引擎線程互斥,那么我們可以得出以下結論JS阻塞頁面加載,那么在js運行的這段時間內,GUI的渲染會停止,這段時間內的界面交互,DOM的重繪與回流會停止,會被保存到待執行隊列中,直到js線程空閑,才會執行這些隊列。
我們用下面的一段代碼和運行結果來說明這個機制:

    
5a58c79d0ab6fba30c56152277a02e50.gif


可以看到,一開始網頁和動畫正常運行,但是開始執行計算斐波那契數列后,動畫就停止了,頁面也停止響應鼠標的click事件了,直到recurFib(40)計算出結果后,動畫才開始繼續執行,而期間積攢的click事件也在一起被執行。這就解釋了GUI渲染線程與JS引擎線程互斥。由于這個弊端HTML5提出Web Worker標準。

利用Web Worker開啟一個子線程

Web Worker 有以下幾個使用注意點。

1.同源限制
分配給 Worker 線程運行的腳本文件,必須與主線程的腳本文件同源。
2.DOM 限制
Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的 DOM 對象,也無法使用document、window、parent這些對象。但是,Worker 線程可以navigator對象和location對象。
3.通信聯系
Worker 線程和主線程不在同一個上下文環境,它們不能直接通信,必須通過消息完成。
4.腳本限制
Worker 線程不能執行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 對象發出 AJAX 請求。
5.文件限制
Worker 線程無法讀取本地文件,即不能打開本機的文件系統(file:),它所加載的腳本,必須來自網絡。
創建Worker時,JS引擎向瀏覽器申請開一個子線程(子線程是瀏覽器開的,完全受主線程控制,而且不能操作DOM)
JS引擎線程與worker線程間通過特定的方式通信(postMessage API,需要通過序列化對象來與線程交互特定的數據)。
下面我們用worker的相關api來解決上面卡頓的問題。

    
// test.js子線程代碼// 通過監聽message來接受主線程中的消息addEventListener('message', function(res) {    // 子線程向主線程中發生消息    // 計算斐波那契數列,這個數列從第3項開始,每一項都等于前兩項之和。    if(res.data === 'start') {        // 開始運算        console.log('收到主線程消息,開始運算')        function recurFib(n) {            if(n < 2){                // 主動關閉子線程                // this.close()                return n ;            }else {                return recurFib(n-1)+recurFib(n-2)            }        }        console.time("運算時間:")        // 計算n為40的結果        var count = recurFib(40)        console.timeEnd("運算時間:")        // 向主線程發送消息        console.log('運算完畢,發送消息給主線程!')        this.postMessage(count);    }})

運行結果:

1a7ab0049f69705279802cf5617b7c84.png

可以看到整個運行過程動畫沒有卡頓,也能響應click事件,所以在我們遇到大型計算的時候,請單獨開啟一個worker子線程來解決js線程阻塞GUI線程的問題。上文中只涉及到一部分worker API。

兼容性

aca56cb2fce32ef21c3f4b17077cb583.png


可以看到除了Opera Mini瀏覽器,連IE都能使用了,所以兼容性問題不大。

總結

  1. 由于javaScript的最初設計特點,采用了單線程的運行機制。
  2. 瀏覽器是多個線程相互協作來工作的,但是GUI渲染線程與JS引擎線程互斥
  3. js線程在運行時,會鎖死GUI渲染線程,為了利用多核CPU的計算能力,HTML5提出Web Worker標準。
  4. Web Worker的使用有一些限制,比如說:同源限制,DOM限制,文件限制等,但能解決在js需要大量計算工作時,頁面卡頓的問題。
  5. Web Worker實際上是js線程的一個子線程,理論上js還是單線程的。

學習如逆水行舟,不進則退,前端技術飛速發展,如果每天不堅持學習,就會跟不上,我會陪著大家,每天堅持推送博文,跟大家一同進步,希望大家能關注我,第一時間收到最新文章。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446130.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446130.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446130.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言深度剖析書籍學習記錄 第三章 預處理

宏 _LINE_ 表示正在編譯的文件的行號_FILE_ 表示正在編譯的文件的名字_DATE_ 表示編譯時刻的日期字符串&#xff0c;例如: "25 Dec 2007"_TIME_ 表示編譯時刻的時間字符串&#xff0c;例如: "12:30:55"_STDC_ 判斷該文件是不是定義成標準 C 程序宏名的書寫…

js正則限制字符串長度_正則筆記(3)萬字長文,慎點。

正則講了很久&#xff0c;也拖了很久&#xff0c;今天看看怎么用吧&#xff0c;后續更文應該會比較準勤快了。:-)書接上文【正則筆記(2)】。這次我們來看看正則的使用&#xff1a;(注&#xff1a;斜體表示為對應規則寫出的正則表達式)一、 常用的正則表達式&#xff1a;1. 驗證…

C語言深度剖析書籍學習記錄 第四章 指針和數組

p 稱為指針變量,p 里存儲的內存地址處的內存稱為 p 所指向的內存。 指針變量 p 里存儲的任何數據都將被當作地址來處理一個基本的數據類型(包括結構體等自定義類型)加上“*” 號就構成了一個指針類型的模子。這個模子的大小是一定的&#xff0c;與“*”號前面的數據類型無 關。…

js中select下拉框重置_如何利用CSS3制作炫酷的下拉框

很多小伙伴都不清楚CSS3是做什么&#xff1f;用途是什么&#xff1f;接下來我就給展示一個css3制作一個炫酷下拉框。其實不只是這些&#xff0c;還有很多。CSS3是CSS(層疊樣式表)技術的升級版本&#xff0c;于1999年開始制訂&#xff0c;2001年5月23日W3C完成了CSS3的工作草案&…

select選擇框必輸校驗_輪子這么多,我們為什么選擇自研NewSQL

作者介紹李鑫&#xff0c;滴滴資深軟件開發工程師&#xff0c;多年分布式存儲領域設計及開發經驗。曾參與NoSQL/NewSQL數據庫Fusion、分布式時序數據庫sentry、NewSQL數據庫SDB等系統的設計開發工作。一、背景Fusion-NewSQL是由滴滴自研的在分布式KV存儲基礎上構建的NewSQL存儲…

C語言深度剖析書籍學習記錄 第五章 內存管理

常見的內存錯誤 定義了指針變量&#xff0c;但是沒有為指針分配內存&#xff0c;即指針沒有指向一塊合法的內存。 結構體成員指針未初始化 很多初學者犯了這個錯誤還不知道是怎么回事。這里定義了結構體變量 stu&#xff0c;但是他沒 想到這個結構體內部 char *name 這成員在定…

怎么改電腦網絡ip地址_拋棄重啟路由器獲取ip地址方式,巧妙運用ip代理改IP工具...

網絡是簡單的也是復雜的&#xff0c;在如此龐大的網絡世界里有太多的不確定因素&#xff0c;導致我們遇到IP限制問題&#xff0c;從而影響到我們的網絡訪問&#xff0c;而大家都知道&#xff0c;如果遇到ip被限制的問題&#xff0c;最快速直接的辦法就是把被限制的ip更換一個新…

C語言深度剖析書籍學習記錄 第六章 函數

函數的好處 1、降低復雜性:使用函數的最首要原因是為了降低程序的復雜性&#xff0c;可以使用函數來隱含信息&#xff0c;從而使你不必再考慮這些信息。2、避免重復代碼段:如果在兩個不同函數中的代碼很相似&#xff0c;這往往意味著分解工作有誤。這時&#xff0c;應該把兩個…

如何把word分裝到兩個byte_如何核對兩個Word文檔的內容差別?同事加班半小時,我只花了30秒...

昨天下班前&#xff0c;老板突然發了兩份Word文檔過來&#xff0c;一份是原稿&#xff0c;還有一份是修訂稿&#xff0c;叫我們找出兩份文檔的內容差別之處&#xff0c;我只花了30秒就搞定了&#xff0c;然后準時下班&#xff01;你想知道我是怎么操作的嗎&#xff1f;下面小源…

stm32f767中文手冊_ALIENTEK 阿波羅 STM32F767 開發板資料連載第五章 SYSTEM 文件夾

1)實驗平臺&#xff1a;alientek 阿波羅 STM32F767 開發板2)摘自《STM32F7 開發指南(HAL 庫版)》關注官方微信號公眾號&#xff0c;獲取更多資料&#xff1a;正點原子第五章 SYSTEM 文件夾介紹第三章&#xff0c;我們介紹了如何在 MDK5 下建立 STM32F7 工程。在這個新建的工程之…

手機安卓學習 內核開發

官網開源代碼 Documentation - MiCode/Xiaomi_Kernel_OpenSource - Sourcegraph Xiaomi 11T Pro GitHub - MiCode/Xiaomi_Kernel_OpenSource: Xiaomi Mobile Phone Kernel OpenSourceAndroid 開源項目 | Android Open Source Project google安卓官網 目錄概覽 參考…

vs 啟動調用的目標發生異常_如何解決不可測、異常場景的問題?

阿里QA導讀&#xff1a;在軟件研發過程中&#xff0c;發布前跨多個系統的聯調測試是不可或缺的一環&#xff0c;而在聯調過程中&#xff0c;經常會遇到一些比較棘手的困難&#xff0c;阻塞整個聯調進程。其中比較典型的有&#xff1a;第三方的研發節奏不一致&#xff0c;導致無…

Linux內核 scatterlist介紹

scatterlist 物理內存的散列表。通俗講&#xff0c;就是把一些分散的物理內存&#xff0c;以列表的形式組織起來 誕生背景 假設有三個模塊可以訪問memory&#xff1a;CPU、DMA控制器和某個外設。CPU通過MMU以虛擬地址&#xff08;VA&#xff09;的形式訪問memory&#xff1b;…

www.python123.org_python爬蟲-requests

Requests庫是目前常用且效率較高的爬取網頁的庫1.一個簡單的例子import requests #引入requests庫r requests.get("http://www.baidu.com")  #調用get方法獲取界面print(r.status_code)    #輸出狀態碼print(r.text)    #輸出頁面信息通過以下代碼&#x…

Linux內核 crypto文件夾 密碼學知識學習

密碼算法分類 對稱算法非對稱算法消息摘要&#xff08;單向哈希&#xff09;算法這些算法作為加密函數框架的最底層&#xff0c;提供加密和解密的實際操作。這些函數可以在內核crypto文件夾下&#xff0c;相應的文件中找到。不過內核模塊不能直接調用這些函數&#xff0c;因為…

python隨機出100道加法題_自動出題隨機100題-20以內加減法全部算式

班 級:姓 名:12-819-411-1114-1018-111417-261215-113-417-819-1914-341516-31269619-161159312817-014-1414-1112-501414-017-616-111-012-211520-711113051019-1810619-691118-1220-519-818018114-1416-712-1015-1319-916-714-920-717-118-1611-815-416-1014-919-416-1413-…

Linux crypto相關知識的匯總 Linux加密框架crypto中的算法和算法模式(一)

Linux加密框架中的算法和算法模式 Linux加密框架中的算法和算法模式&#xff08;一&#xff09;_家有一希的博客-CSDN博客 加密框架支持的密碼算法主要是對稱密碼算法和哈希算法&#xff0c;暫時不支持非對稱密碼算法。除密碼算法外&#xff0c;加密框架還包括偽隨機數生成算法…

python3.5.2安裝pygame_【閑來無事,py寫game】Mac-Python3.5安裝pygame 1.9.2 小計

13正文之前沒錯&#xff0c;我就是這么不學無術&#xff0c;C實在學的雞兒疼&#xff0c;所以干脆搞點娛樂措施&#xff0c;昨天趕上了京東圖書做大活動&#xff0c;所以屯了一批書&#xff0c;好久沒碰python了。所以就整本玩玩&#xff01;今天這不就上手了么&#xff01;自己…

Linux crypto相關知識的匯總 Linux加密框架crypto對稱算法和哈希算法加密模式

參考鏈接 Linux加密框架中的算法和算法模式&#xff08;二&#xff09;_家有一希的博客-CSDN博客 對稱算法 分組算法模式 ECB模式 ECB模式下&#xff0c;明文數據被分為大小合適的分組&#xff0c;然后對每個分組獨立進行加密或解密如下圖所示如果兩個明文塊相同&#xff0c…