目錄
#4.單執行緒與多執行緒的優缺點?
三、定時器引發的思考
1. 定時器真是定時執行的嗎?
2. Web Workers的基本使用
首頁 web前端 js教程 js線程機制與事件機制的詳細介紹(圖文)

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

Oct 16, 2018 pm 02:08 PM
css html java javascript vue.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/imghw/default1.png" data-src="https://img.php.cn//upload/image/139/417/140/1539669885863938.png" 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/imghw/default1.png" data-src="https://img.php.cn//upload/image/280/170/433/1539669867171806.png" 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/imghw/default1.png" data-src="https://img.php.cn//upload/image/673/101/817/1539670027106347.gif" 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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱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

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML:結構,CSS:樣式,JavaScript:行為 HTML:結構,CSS:樣式,JavaScript:行為 Apr 18, 2025 am 12:09 AM

HTML、CSS和JavaScript在Web開發中的作用分別是:1.HTML定義網頁結構,2.CSS控製網頁樣式,3.JavaScript添加動態行為。它們共同構建了現代網站的框架、美觀和交互性。

HTML的未來:網絡設計的發展和趨勢 HTML的未來:網絡設計的發展和趨勢 Apr 17, 2025 am 12:12 AM

HTML的未來充滿了無限可能。 1)新功能和標準將包括更多的語義化標籤和WebComponents的普及。 2)網頁設計趨勢將繼續向響應式和無障礙設計發展。 3)性能優化將通過響應式圖片加載和延遲加載技術提升用戶體驗。

PHP的影響:網絡開發及以後 PHP的影響:網絡開發及以後 Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

了解vue.js:主要是前端框架 了解vue.js:主要是前端框架 Apr 17, 2025 am 12:20 AM

Vue.js是由尤雨溪在2014年發布的漸進式JavaScript框架,用於構建用戶界面。它的核心優勢包括:1.響應式數據綁定,數據變化自動更新視圖;2.組件化開發,UI可拆分為獨立、可複用的組件。

PHP與Python:用例和應用程序 PHP與Python:用例和應用程序 Apr 17, 2025 am 12:23 AM

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。

解決 Craft CMS 中的緩存問題:使用 wiejeben/craft-laravel-mix 插件 解決 Craft CMS 中的緩存問題:使用 wiejeben/craft-laravel-mix 插件 Apr 18, 2025 am 09:24 AM

在使用CraftCMS開發網站時,常常會遇到資源文件緩存的問題,特別是當你頻繁更新CSS和JavaScript文件時,舊版本的文件可能仍然被瀏覽器緩存,導致用戶無法及時看到最新的更改。這個問題不僅影響用戶體驗,還會增加開發和調試的難度。最近,我在項目中遇到了類似的困擾,經過一番探索,我找到了wiejeben/craft-laravel-mix這個插件,它完美地解決了我的緩存問題。

解構H5代碼:標籤,元素和屬性 解構H5代碼:標籤,元素和屬性 Apr 18, 2025 am 12:06 AM

HTML5代碼由標籤、元素和屬性組成:1.標籤定義內容類型,用尖括號包圍,如。 2.元素由開始標籤、內容和結束標籤組成,如內容。 3.屬性在開始標籤中定義鍵值對,增強功能,如。這些是構建網頁結構的基本單位。

vue.js:定義其在網絡開發中的作用 vue.js:定義其在網絡開發中的作用 Apr 18, 2025 am 12:07 AM

Vue.js在Web開發中的角色是作為一個漸進式JavaScript框架,簡化開發過程並提高效率。 1)它通過響應式數據綁定和組件化開發,使開發者能專注於業務邏輯。 2)Vue.js的工作原理依賴於響應式系統和虛擬DOM,優化性能。 3)實際項目中,使用Vuex管理全局狀態和優化數據響應性是常見實踐。

See all articles