搜尋
首頁web前端js教程js線程機制與事件機制的詳細介紹(圖文)

js線程機制與事件機制的詳細介紹(圖文)

Oct 16, 2018 pm 02:08 PM
csshtmljavajavascriptvue.js

這篇文章帶給大家的內容是關於js線程機制與事件機制的詳細介紹(圖文),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

js線程機制與事件機制的詳細介紹(圖文)

一、行程與執行緒

1.行程

#進程是指程式的一次執行,它佔有一片獨有的記憶體空間,可以透過windows任務管理器查看進程(如下圖)。在同一個時間裡,同一個電腦系統中允許兩個或兩個以上的進程處於並行狀態,這是多進程。例如電腦同時運行微信,QQ,以及各種瀏覽器等。 瀏覽器運行是有些是單進程,如firefox和舊版IE,有些是多進程,如chrome和新版IE

js線程機制與事件機制的詳細介紹(圖文)js線程機制與事件機制的詳細介紹(圖文)

2.執行緒

#有些行程不只同時做一件事,例如Word,它可以同時進行打字、拼字檢查、列印等事情。在一個進程內部,要同時幹多件事,就需要同時運行多個“子任務”,我們把進程內的這些“子任務”稱為線程(Thread)。
執行緒是指CPU的基本調度單位,是程式執行的一個完整流程,是進程內的一個獨立執行單元。多執行緒是指在一個行程內, 同時有多個執行緒運行。 瀏覽器運行是多執行緒。例如用瀏覽器一邊下載,一邊聽歌,一邊看影片。另外我們需要知道JavaScript語言的一大特點就是單線程,為了利用多核心CPU的運算能力,HTML5提出Web Worker標準,讓JavaScript腳本建立多個線程,但子執行緒完全受主執行緒控制,且不得操作DOM。所以,這個新標準並沒有改變JavaScript單執行緒的本質

js線程機制與事件機制的詳細介紹(圖文)

由於每個行程至少要做一件事,所以,一個行程至少有一個執行緒。當然,像Word這種複雜的進程可以有多個線程,多個線程可以同時執行,多線程的執行方式和多進程是一樣的,也是由作業系統在多個線程之間快速切換,讓每個線程都短暫地交替運行,看起來就像同時執行一樣。當然,真正地同時執行多執行緒需要多核心CPU才可能實現。

3.行程與執行緒

  • 應用程式必須執行在某個行程的某個執行緒上

  • 一個行程中至少有一個運行的執行緒: 主執行緒,  行程啟動後自動建立

  • #一個行程如果同時執行多個執行緒, 那這個程式是多執行緒執行的

  • 一個行程的記憶體空間是共享的,每個執行緒都可以使用這些共享記憶體。

  • 多個行程之間的資料是不能直接共享的

#4.單執行緒與多執行緒的優缺點?

單執行緒的優點:順序程式設計簡單易懂

單執行緒的缺點:效率低

多執行緒的優點:能有效提升CPU的使用率

多執行緒的缺點:

  • ## 建立多執行緒開銷

  • 執行緒間切換開銷

  • #死鎖與狀態同步問題

二、瀏覽器核心

瀏覽器的核心是指支援瀏覽器運行的最核心的程序,分為兩個部分的,一是渲染引擎,另一個是JS引擎。現在JS引擎比較獨立,核心更傾向說渲染引擎。

1.不同的瀏覽器可能不太一樣

  • Chrome, Safari: webkit

  • firefox: Gecko

  • IE: Trident

  • 360,搜狗等國內瀏覽器: Trident webkit

2.內核由許多模組組成

  • 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()之后')

js線程機制與事件機制的詳細介紹(圖文)

有兩點我們需要注意下:

  • #計時器零延遲(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(&#39;number&#39;)
  document.getElementById(&#39;btn&#39;).onclick = function () {
    var number = input.value
    var result = fibonacci(number)
    alert(result)
  }
</script>

js線程機制與事件機制的詳細介紹(圖文)

很显然遇到这种页面堵塞情况,很影响用户体验的,有没有啥办法可以改进这种情形?----Web Worker就应运而生了!

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。其原理图如下:

js線程機制與事件機制的詳細介紹(圖文)

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中文網其他相關文章!

陳述
本文轉載於:segmentfault思否。如有侵權,請聯絡admin@php.cn刪除
Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

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

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

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

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

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

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

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

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

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

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

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

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

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

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

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

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

SublimeText3 英文版

SublimeText3 英文版

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

Safe Exam Browser

Safe Exam Browser

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

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器