這篇文章帶給大家的內容是關於js線程機制與事件機制的詳細介紹(圖文),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
一、行程與執行緒
1.行程
#進程是指程式的一次執行,它佔有一片獨有的記憶體空間,可以透過windows任務管理器查看進程(如下圖)。在同一個時間裡,同一個電腦系統中允許兩個或兩個以上的進程處於並行狀態,這是多進程。例如電腦同時運行微信,QQ,以及各種瀏覽器等。 瀏覽器運行是有些是單進程,如firefox和舊版IE,有些是多進程,如chrome和新版IE。
2.執行緒
#有些行程不只同時做一件事,例如Word,它可以同時進行打字、拼字檢查、列印等事情。在一個進程內部,要同時幹多件事,就需要同時運行多個“子任務”,我們把進程內的這些“子任務”稱為線程(Thread)。
執行緒是指CPU的基本調度單位,是程式執行的一個完整流程,是進程內的一個獨立執行單元。多執行緒是指在一個行程內, 同時有多個執行緒運行。 瀏覽器運行是多執行緒。例如用瀏覽器一邊下載,一邊聽歌,一邊看影片。另外我們需要知道JavaScript語言的一大特點就是單線程,為了利用多核心CPU的運算能力,HTML5提出Web Worker標準,讓JavaScript腳本建立多個線程,但子執行緒完全受主執行緒控制,且不得操作DOM。所以,這個新標準並沒有改變JavaScript單執行緒的本質。
由於每個行程至少要做一件事,所以,一個行程至少有一個執行緒。當然,像Word這種複雜的進程可以有多個線程,多個線程可以同時執行,多線程的執行方式和多進程是一樣的,也是由作業系統在多個線程之間快速切換,讓每個線程都短暫地交替運行,看起來就像同時執行一樣。當然,真正地同時執行多執行緒需要多核心CPU才可能實現。
3.行程與執行緒
應用程式必須執行在某個行程的某個執行緒上
一個行程中至少有一個運行的執行緒: 主執行緒, 行程啟動後自動建立
#一個行程如果同時執行多個執行緒, 那這個程式是多執行緒執行的
一個行程的記憶體空間是共享的,每個執行緒都可以使用這些共享記憶體。
多個行程之間的資料是不能直接共享的
#4.單執行緒與多執行緒的優缺點?
單執行緒的優點:順序程式設計簡單易懂
單執行緒的缺點:效率低
多執行緒的優點:能有效提升CPU的使用率
多執行緒的缺點:
- ## 建立多執行緒開銷
- 執行緒間切換開銷
- #死鎖與狀態同步問題
- Chrome, Safari: webkit
- firefox: Gecko
- IE: Trident
- 360,搜狗等國內瀏覽器: Trident webkit
- html,css文件解析模組: 負責頁面文字的解析
- dom/css模組: 負責dom/css在記憶體中的相關處理
- 佈局和渲染模組: 負責頁面的佈局和效果的繪製
- 定時器模組: 負責定時器的管理
- 網路請求模組: 負責伺服器請求(常規/Ajax)
- 事件回應模組: 負責事件的管理
三、定時器引發的思考
1. 定時器真是定時執行的嗎?
我們先來看個例子,試問定時器會保證200ms後執行嗎?
document.getElementById('btn').onclick = function () { var start = Date.now() console.log('启动定时器前...') setTimeout(function () { console.log('定时器执行了', Date.now() - start) }, 200) console.log('启动定时器后...') // 做一个长时间的工作 for (var i = 0; i <p style="text-align: center;"><span class="img-wrap"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn//upload/image/139/417/140/1539669885863938.png?x-oss-process=image/resize,p_40" class="lazy" title="1539669885863938.png" alt="js線程機制與事件機制的詳細介紹(圖文)"></span><br>事實上,經過了625ms後定時器才執行。定時器並不能保證真正定時執行,一般會延遲一丁點,也有可能延遲很長時間(比如上面的例子)</p><p><strong>2.定時器回調函數是在分線程執行的嗎? </strong></p><p><strong>定時器回呼函數在主執行緒執行的</strong>, 具體實作方式下文會介紹。 </p><p><strong>四、瀏覽器的事件循環(輪詢)模型</strong></p><p><strong>1. 為什麼JavaScript是單執行緒</strong></p><p><strong>JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能做一件事</strong>。那麼,為什麼JavaScript不能有多個執行緒呢?這樣能提高效率啊。 </p><p>JavaScript的單線程,與它的用途有關。作為瀏覽器腳本語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它只能是單線程,否則會帶來複雜的同步問題。例如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,而這時瀏覽器應該以哪個線程為準? </p><p>所以,為了避免複雜性,從一誕生,JavaScript就是單線程,這已經變成了這門語言的核心特徵,將來也不會改變。 <br>為了利用多核心CPU的運算能力,<strong>HTML5提出Web Worker標準,允許JavaScript腳本建立多個線程,但是子執行緒完全受主執行緒控制,且不得操作DOM</strong>。所以,這個新標準並沒有改變JavaScript單執行緒的本質。 </p><p><strong>2.Event Loop</strong></p><p>JavaScript中所有任務可以分成兩種,一種是同步任務,另一種是非同步任務(如各種瀏覽器事件、定時器和Ajax等)。 <strong>同步任務指的是,在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;非同步任務指的是,不進入主執行緒、而進入"任務佇列"(task queue)的任務,只有"任務隊列"通知主線程,某個非同步任務可以執行了,該任務才會進入主執行緒執行</strong>。 </p><p>具體來說,非同步執行的運作機制如下。 (同步執行也是如此,因為它可以被視為沒有非同步任務的非同步執行。)</p><p>(1)所有同步任務都在主執行緒上執行,形成一個執行堆疊(execution context stack)。 </p><p>(2)主執行緒之外,還存在一個"任務佇列"(task queue)。只要非同步任務有了運行結果,就在"任務隊列"之中放置一個事件。 </p><p>(3)一旦"執行堆疊"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。 </p><p>(4)主執行緒不斷重複上面的第三步</p><p><strong>主執行緒從"任務佇列"中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為Event Loop(事件循環)</strong></p><p style="max-width:90%"><span class="img-wrap"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn//upload/image/280/170/433/1539669867171806.png?x-oss-process=image/resize,p_40" class="lazy" title="1539669867171806.png" alt="js線程機制與事件機制的詳細介紹(圖文)"></span><br>#下面這個範例很好闡釋事件循環:</p><pre class="brush:php;toolbar:false"> setTimeout(function () { console.log('timeout 2222') alert('22222222') }, 2000) setTimeout(function () { console.log('timeout 1111') alert('1111111') }, 1000) setTimeout(function () { console.log('timeout() 00000') }, 0)//当指定的值小于 4 毫秒,则增加到 4ms(4ms 是 HTML5 标准指定的,对于 2010 年及之前的浏览器则是 10ms) function fn() { console.log('fn()') } fn() console.log('alert()之前') alert('------') //暂停当前主线程的执行, 同时暂停计时, 点击确定后, 恢复程序执行和计时 console.log('alert()之后')
有兩點我們需要注意下:
#計時器零延遲(setTimeout(func, 0))並不是意味著回調函數立刻執行。至少4ms,才會執行回呼函數。它取決於主執行緒目前是否空閒與「任務佇列」裡其前面正在等待的任務。
只有在到達指定時間時,計時器就會將對應回呼函數插入「任務佇列」尾部
總結:非同步任務(各種瀏覽器事件、計時器和Ajax等)都是先加入到「任務佇列」(計時器則到達其指定參數時)。當 Stack 堆疊(JavaScript 主執行緒)為空時,就會讀取 Queue 佇列(任務佇列)的第一個任務(隊首),最後執行。
五、H5 Web Workers(多執行緒)
#1. Web Workers的作用
如上所提到,JavaScript是單執行緒。當一個頁面載入一個複雜運算的 js 檔案時,使用者介面可能會短暫地“凍結”,不能再做其他操作。比如下面這個例子:
<input> <button>计算</button> <script> // 1 1 2 3 5 8 f(n) = f(n-1) + f(n-2) function fibonacci(n) { return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2) //递归调用 } var input = document.getElementById('number') document.getElementById('btn').onclick = function () { var number = input.value var result = fibonacci(number) alert(result) } </script>
很显然遇到这种页面堵塞情况,很影响用户体验的,有没有啥办法可以改进这种情形?----Web Worker就应运而生了!
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。其原理图如下:
2. Web Workers的基本使用
主线程
首先主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程
var worker = new Worker('work.js');
然后主线程调用worker.postMessage()方法,向 Worker 发消息。
接着,主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息。
var input = document.getElementById('number') document.getElementById('btn').onclick = function () { var number = input.value //创建一个Worker对象 var worker = new Worker('worker.js') // 绑定接收消息的监听 worker.onmessage = function (event) { console.log('主线程接收分线程返回的数据: '+event.data) alert(event.data) } // 向分线程发送消息 worker.postMessage(number) console.log('主线程向分线程发送数据: '+number) } console.log(this) // window
Worker 线程
Worker 线程内部需要有一个监听函数,监听message事件。
通过 postMessage(data) 方法来向主线程发送数据。
//worker.js文件 function fibonacci(n) { return n<p>这样当分线程在计算时,用户界面还可以操作,而且更早拿到计算后数据,响应速度更快了。</p><p style="text-align: center;"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn//upload/image/673/101/817/1539670027106347.gif?x-oss-process=image/resize,p_40" class="lazy" title="1539670027106347.gif" alt="js線程機制與事件機制的詳細介紹(圖文)"><span class="img-wrap"></span></p><p><strong>3. Web Workers的缺点</strong></p>
不能跨域加载JS
worker内代码不能访问DOM(更新UI)
不是每个浏览器都支持这个新特性(本文例子只能在Firefox浏览器上运行,chrome不支持)
以上是js線程機制與事件機制的詳細介紹(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1
強大的PHP整合開發環境

Atom編輯器mac版下載
最受歡迎的的開源編輯器

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器