日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

多线程读取同一个文件_前端进阶:多线程Web Workers的工作原理及使用场景

發布時間:2024/4/11 HTML 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程读取同一个文件_前端进阶:多线程Web Workers的工作原理及使用场景 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Web Worker 概述

Web Worker 的作用,就是為 JavaScript 創造多線程環境,允許主線程創建 Worker 線程,將一些任務分配給后者運行。在主線程運行的同時,Worker 線程在后臺運行,兩者互不干擾。等到 Worker 線程完成計算任務,再把結果返回給主線程。這樣的好處是,一些計算密集型或高延遲的任務,被 Worker 線程負擔了,主線程(通常負責 UI 交互)就會很流暢,不會被阻塞或拖慢。

你可能會問:“JavaScript不是一個單線程的語言嗎?”

事實上 JavaScript 是一種不定義線程模型的語言。Web Workers 不是 JavaScript 的一部分,而是可以通過 JavaScript 訪問的瀏覽器特性。歷史上,大多數瀏覽器都是單線程的(當然,這已經改變了),大多數 JavaScript 實現都是發生在瀏覽器中。Web Workers 不是在 Node.JS 中實現的。Node.js 中有類似的集群(cluster)、子進程概念(child_process),他們也是多線程,但是和 Web Workers 還是有區別 。

值得注意的是,規范中提到了三種類型的 Web Workers:

  • 專用 Workers (Dedicated Workers)
  • 共享 Workers (Shared Workers)
  • 服務 Workers (Service workers)

Dedicated Workers

專用 Workers 只能被創建它的頁面訪問,并且只能與它通信。以下是瀏覽器支持的情況:

Shared Workers

共享 Workers 在同一源(origin)下面的各種進程都可以訪問它,包括:iframes、瀏覽器中的不同tab頁(一個tab頁就是一個單獨的進程,所以Shared Workers可以用來實現 tab 頁之間的交流)、以及其他的共享 Workers。以下是瀏覽器支持的情況:

Service workers

Service Worker 功能:

  • 后臺消息傳遞
  • 網絡代理,轉發請求,偽造響應
  • 離線緩存
  • 消息推送

在目前階段,Service Worker 的主要能力集中在網絡代理和離線緩存上。具體的實現上,可以理解為 Service Worker 是一個能在網頁關閉時仍然運行的 Web Worker。以下是瀏覽器支持的情況:

本文主要討論 專用 Workers,沒有特別聲明的話,Web Workers、Workers都是指代的專用 Workers。

Web Workers 是如何工作

Web Workers 一般通過腳本為 .js 文件來構建,在頁面中還通過了一些異步的 HTTP 請求,這些請求是完全被隱藏了的,你只需要調用 Web Worker API。

Worker 利用類線程間消息傳遞來實現并行性。它們保證界面的實時性、高性能和響應性呈現給用戶。

Web Workers 在瀏覽器中的一個獨立線程中運行。因此,它們執行的代碼需要包含在一個**單獨的文件中**。這一點很重要,請記住!

讓我們看看基本 Workers 是如何創建的:

var worker = new Worker('task.js');

Worker() 構造函數的參數是一個腳本文件,該文件就是 Worker 線程所要執行的任務。由于 Worker 不能讀取本地文件,所以這個腳本必須來自網絡。如果下載沒有成功(比如404錯誤),Worker 就會默默地失敗。

為了啟動創建的 Worker,需要調用 postMessage 方法:

worker.postMessage();

Web Worker 通信

為了在 Web Worker 和創建它的頁面之間進行通信,需要使用 postMessage 方法或 Broadcast Channel。

postMessage 方法

新瀏覽器支持JSON對象作為方法的第一個參數,而舊瀏覽器只支持字符串。

來看一個示例,通過將 JSON 對象作為一個更“復雜”的示例傳遞,創建 Worker 的頁面如何與之通信。傳遞字符串跟傳遞對象的方式也是一樣的。

讓我們來看看下面的 HTML 頁面(或者更準確地說是它的一部分):

然后這是 worker 中的 js 代碼:

當單擊該按鈕時,將從主頁調用 postMessage。postMessage 行將 JSON 對象傳給 Worker。Worker 通過定義的消息處理程序監聽并處理該消息。

當消息到達時,實際的計算在worker中執行,而不會阻塞事件循環。Worker 檢查傳遞的事件參數 `e`,像執行 JavaScript 函數一樣,處理完成后,把結果傳回給主頁。

在 Worker 作用域中,this 和 self 都指向 Worker 的全局作用域。

有兩種方法可以停止 Worker:從主頁調用 worker.terminate()或在 worker 內部調用 self.close()。

Broadcast Channel

Broadcast Channel API 允許同一原始域和用戶代理下的所有窗口,iFrames 等進行交互。也就是說,如果用戶打開了同一個網站的的兩個標簽窗口,如果網站內容發生了變化,那么兩個窗口會同時得到更新通知。

還是不明白?就拿 Facebook 作為例子吧,假如你現在已經打開 了Facebook 的一個窗口,但是你此時還沒有登錄,此時你又打開另外一個窗口進行登錄,那么你就可以通知其他窗口/標簽頁去告訴它們一個用戶已經登錄了并請求它們進行相應的頁面更新。

可以從下面這張圖,在視覺上來清晰地感受 Broadcast Channel:

Broadcast Channel 瀏覽器支持比較有限:

消息的大小

有兩種方式發送消息給Web Workers:

復制消息:消息被序列化、復制、發送,然后在另一端反序列化。頁面和 Worker 不共享相同的實例,因此最終的結果是每次傳遞都會創建一個副本大多數瀏覽器,在兩邊都是使用的JSON對值進行編碼和解碼,這樣對數據的解碼、編碼操作,勢必會增加消息傳輸過程的時間開銷。信息越大,發送的時間就越長。

傳遞消息:這意味著原始發送方在一旦發送后不能再使用它。傳輸數據幾乎是瞬間的,這種傳輸方式的局限性在于只能用 ArrayBuffer 類型來傳遞。

Web Workers 可用的特性

Web Workers 由于具有多線程特性,因此只能訪問 JavaScript 特性的子集。 以下是可使用特性列表:

  • navigator 對象
  • location 對象(只讀)
  • XMLHttpRequest
  • setTimeout()/clearTimeout() and setInterval()/clearInterval()
  • 應用緩存(Application Cache)
  • 使用 importScripts() 導入外部腳本
  • 創建其他的 Web Workers

Web Workers 的局限性

同源限制

分配給 Worker 線程運行的腳本文件,必須與主線程的腳本文件同源。

DOM 限制

Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的 DOM 對象,也無法使用document、window、parent這些對象。這意味著 Web Worker 不能操作 DOM (因此也不能操作 UI)。有時這可能很棘手,但是一旦你了解了如何正確使用 Web Workers,你就會開始將它們作為單獨的“計算機”使用,而所有 UI 更改都將發生在你的頁面代碼中。 Workers 將為你完成所有繁重的工作,然后一旦完成再把結果返回給 page 頁面。

通信聯系

Worker 線程和主線程不在同一個上下文環境,它們不能直接通信,必須通過消息完成。

腳本限制

Worker 線程不能執行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 對象發出 AJAX 請求。

文件限制

Worker 線程無法讀取本地文件,即不能打開本機的文件系統(file://),它所加載的腳本,必須來自網絡。

處理錯誤

和 JavaScript 代碼一樣,Web workers 里拋出的錯誤,你也需要進行處理。當 Worker 執行過程中如果遇到錯誤,會觸發一個 `ErrorEvent` 事件。接口包含了三個有用的屬性來幫忙排查問題:

filename - 導致 Worker 的腳本名稱

lineno - 發生錯誤的行號

message - 對錯誤的描述

例子如下:

在這里,可以看到我們創建了一個 worker 并開始偵聽錯誤事件。

在 worker 內部(在 workerWithError.js 中),我們通過將未定義 x 乘以 2 來創建一個異常。異常被傳播到初始腳本,然后通過頁面監聽 error事件,對錯誤進行捕獲。

Web Workers 應用實例

到目前為止,我們已經列出了 Web Workers 的優點和局限性?,F在讓我們看看它們最強大的用例是什么:

Ray tracing(光線追蹤):光線追蹤是一種以像素為單位跟蹤光的路徑生成圖像的渲染技術。光線追蹤利用 CPU 密集型的數學計算來模擬光的路徑。其思想是模擬一些效果,如反射、折射、材料等。所有這些計算邏輯都可以添加到 Web Worker 中,以避免阻塞 UI線程。更好的是——可以很容易地在多個 workers 之間(以及在多個cpu之間)分割圖像呈現。下面是一個使用 Web Workers 的光線追蹤的簡單演示—https://nerget.com/rayjs-mt/rayjs.html。

Encryption(加密):由于對個人和敏感數據的監管越來越嚴格,端到端加密越來越受歡迎。加密是一件非常耗時的事情,特別是如果有很多數據需要頻繁加密(例如,在發送到服務器之前)。這是一個使用 Web Worker 非常好的場景,因為它不需要訪問 DOM 或任何花哨的東西——它是完成其工作的純算法。只要是在 Web Worker 中工作的,對于端用戶就是無縫的,不會影響到體驗。

Prefetching data(預取數據):為了優化你的網站或 web 應用程序并改進數據加載時間,你可以利用 Web Workers 提前加載和存儲一些數據,以便在需要時稍后使用。Web Workers 在這種情況下非常棒,因為它們不會影響應用程序的UI,這與不使用Workers 時是不同的。

Progressive Web Apps(漸進式Web應用程序):這種漸進式Web應用程序要求,即使在用戶網絡不穩定的條件下,也能夠迅速的加載。這意味著數據必須本地存儲在瀏覽器中。這也是 IndexDB 或類似 api 發揮作用的地方。通常情況下,客戶端的存儲都是必要的,但使用起來需要不阻塞UI渲染線程,那么工作就需要在 Worker 中進行了。不過,以IndexDB 為例,它提供了一些異步的API,調用它們的話也不需要使用 web worker,但如果是同步的 API,就必須要在 Worker 中使用了。

Spell checking(拼寫檢查):一個基本的拼寫檢查程序的工作流程如下-程序讀取一個字典文件與一個正確拼寫單詞列表。字典被解析為一個搜索樹,以使實際的文本搜索更有效。當一個單詞被提供給檢查器時,程序檢查它是否存在于預先構建的搜索樹中。如果在樹中沒有找到該單詞,可以通過替換替換字符并測試它是否是有效的單詞(如果是用戶想要寫的單詞),為用戶提供替代拼寫。所有的這些處理過程都可以在 Web Worker中進行了,用戶可以不被阻塞的輸入詞匯和句子,Web Worker 在后臺校驗詞匯是否正確以及提供備選詞匯。

總結

以上是生活随笔為你收集整理的多线程读取同一个文件_前端进阶:多线程Web Workers的工作原理及使用场景的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。