Web Workers 客戶端 + 服務端應用

一. Web Workers 客戶端應用

使用 JavaScript 創建 Web Worker 的步驟如下:

1.創建一個新的 JavaScript 文件,其中包含要在工作線程中運行的代碼(耗時任務)。該文件不應包含對 DOM 的引用,因為在工作線程中無法訪問 DOM。

2.在主 JavaScript 文件中,使用?Worker?構造函數創建一個新的worker對象。此構造函數接收一個參數,即在步驟 1 中創建的 JavaScript 文件的 URL。

?
const?worker?=?new?Worker('worker.js');

3.向worker對象添加事件偵聽器以處理主線程和工作線程之間發送的消息。onmessage?用于處理從工作線程發送來的消息,postMessage?用于向工作線程發送消息。

?
worker.onmessage?=?function(event)?{console.log('Worker:?'?+?event.data);
};worker.postMessage('Hello,?worker!');

4.在 Web Worker 的 JavaScript 文件中,使用self對象的onmessage屬性添加一個事件監聽器來處理從主線程發出的消息。可以使用event.data屬性訪問發送的消息數據。

?
self.onmessage?=?function(event)?{console.log('Main:?'?+?event.data);self.postMessage('Hello,?Main!');
};

接下來就運行應用并測試 Worker。可以在控制臺看到以下信息,表示主線程和 Worker 線程之間發送和接收了消息。

?
Main:Hello?worker!
Worker:Hello?Main!

我們可以使用terminate()函數來終止一個工作線程,或者通過調用self上的close()函數使其自行終止。

?
//?從應用中終止一個工作線程
worker.terminate();
//?讓一個工作線程自行終止
self.close();

可以使用importScripts()函數將庫或文件導入到工作線程中,該函數可以接受多個文件。以下示例將script1.jsscript2.js加載到工作線程?worker.js?中:

?
importScripts('script1.js','script2');

可以使用?onerror函數來處理工作線程拋出的錯誤:

?
worker.onerror?=?function(err)?{console.log("遇到錯誤")
}

二. Web Workers 服務端應用

服務器端 JavaScript 運行時也支持 Web Worker:

  • Node.js 在版本 10 中實現了類似 Web Worker 的功能,稱為 Worker thread(工作進程)。

  • Deno 復制了 Web Worker API,因此語法與瀏覽器代碼完全相同。它還提供了兼容模式,可以填充 Node.js API,以便可以使用該運行時的工作線程語法。

  • Bun 將支持瀏覽器和 Node.js 的 Web Worker API。

1. 基本使用

要在 Node.js 中使用 Web Worker,主腳本必須定義一個?Worker?對象,其中包含相對于項目根目錄的 Web Worker 腳本的名稱。第二個參數定義了一個對象,其中包含一個workerData屬性,該屬性包含要發送的數據:

?
const?worker?=?new?Worker('./worker.js',?{workerData:?{?a:?1,?b:?2,?c:?3?}
});

與瀏覽器中的 Web Worker 不同, 它在啟動時無需運行worker.postMessage()。如果需要的話,可以調用該方法并稍后發送更多數據,它會觸發parentPort.on('message')事件處理程序:

?
parentPort.on('message',?e?=>?{console.log(e);
});

一旦工作線程完成處理,它會使用以下方法將結果數據發送回主線程:

?
parentPort.postMessage(result);

這將在在主腳本中觸發?message?事件,主線程接收到 worker 返回的結果:

?
worker.on('message',?result?=>?{console.log(?result?);
});

在發送完消息后,worker 就會終止。這也會觸發一個exit事件,如果希望運行清理或其他函數,可以利用這個事件:

?
worker.on('exit',?code?=>?{//...
});

除此之外,還支持其他事件處理:

  • messageerror:當 worker 收到無法反序列化的數據時觸發。

  • online:當 worker 開始執行時觸發。

  • error:當 worker 腳本中發生 JavaScript 錯誤時觸發。

在服務端,一個單獨的 Node.js 腳本文件可以同時包含主線程和工作線程的代碼。腳本必須使用isMainThread檢查自身是否在主線程上運行,然后將自身作為工作線程進行調用(可以在 ES 模塊中使用import.meta.url作為文件引用,或者在 CommonJS 中使用__filename)。

?
import?{?Worker,?isMainThread,?workerData,?parentPort?}?from?"node:worker_threads";if?(isMainThread)?{//?主線程const?worker?=?new?Worker(import.meta.url,?{workerData:?{?a:?1,?b:?2,?c:?3?}});worker.on('message',?msg?=>?{});worker.on('exit',?code?=>?{});
}
else?{//?工作線程const?result?=?runSomeProcess(?workerData?);parentPort.postMessage(result);
}

這種方式更快,并且對于小型、自包含的單腳本項目來說是一個選擇。如果是大型項目,將 worker 腳本文件分開會更容易維護。

2. 數據通信

主線程和工作線程之間的通信涉及到了數據序列化。可以使用表示固定長度原始二進制數據的SharedArrayBuffer對象在線程之間共享數據。以下是一個示例,主線程定義了從 0 到 99 的 100 個數字元素,并將其發送給工作線程:

?
//?main.js
import?{?Worker?}?from?"node:worker_threads";constbuffer?=?new?SharedArrayBuffer(100?*?Int32Array.BYTES_PER_ELEMENT),value?=?new?Int32Array(buffer);value.forEach((v,i)?=>?value[i]?=?i);const?worker?=?new?Worker('./worker.js');worker.postMessage({?value?});

工作線程可以接收?value對象:

?
//?worker.js
import?{?parentPort?}?from?'node:worker_threads';parentPort.on('message',?value?=>?{value[0]?=?100;
});

主線程或工作線程都可以更改值數組中的元素,數據將在兩個線程之間保持一致。這可能會提高性能,但有一些缺點:

  • 只能共享整數數據。

  • 可能仍需要通知另一個線程更改。

  • 存在兩個線程可能同時更新同一值并且失去同步的風險。

3. Node.js 子進程

在 Node.js 中,除了使用工作線程外,還可以使用子進程來實現類似的功能。子進程用于啟動其他應用、傳遞數據并接收結果。它們與工作線程類似,但通常效率較低,進程開銷較大。

子進程和工作線程的選擇取決于具體的應用場景。如果只需要在 Node.js 中執行其他任務或命令,子進程是一種更好的選擇。但如果需要在 Node.js 中進行復雜的計算或處理任務,Web Worker 可能更適合。

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

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

相關文章

大模型工具Ollama存在安全風險

國家網絡安全通報中心:大模型工具Ollama存在安全風險 來源:國家網絡與信息安全信息通報中心 3月3日,國家網絡安全通報中心發布關于大模型工具Ollama存在安全風險的情況通報,內容如下: 據清華大學網絡空間測繪聯合研…

LINUX系統安裝+添加共享目錄

一、前言 Windows或mac系統中創建Linux工作環境是基于VMware和SL(Scientific Linux),下面分別安裝二者。 二、VMware軟件安裝及注冊 1、雙擊VMware安裝包 2、點擊下一步 3、 勾選接受許可,并點擊下一步 4、更改路徑(建議更改為容易找到的路…

BI 工具響應慢?可能是 OLAP 層拖了后腿

在數據驅動決策的時代,BI 已成為企業洞察業務、輔助決策的必備工具。然而,隨著數據量激增和分析需求復雜化,BI 系統“卡”、“響應慢”的問題日益突出,嚴重影響分析效率和用戶體驗。 本文將深入 BI 性能問題的根源,并…

基于SSM+Vue的汽車維修保養預約系統+LW示例

1.項目介紹 系統角色:管理員、員工、用戶功能模塊:用戶管理、員工管理、汽車類型管理、項目類型管理、維修/預約訂單管理、系統管理、公告管理等技術選型:SSM,vue(后端管理web),Layui&#xff…

在rocklinux里面批量部署安裝rocklinx9

部署三臺Rockylinux9服務器 實驗要求 1. 自動安裝ubuntu server20以上版本 2. 自動部署三臺Rockylinux9服務器,最小化安裝,安裝基礎包,并設定國內源,設靜態IP 實驗步驟 安裝軟件 # yum源必須有epel源 # dnf install -y epel-re…

Oxidized收集H3C交換機網絡配置報錯,not matching configured prompt (?-mix:^(<CD>)$)

背景:問題如上標題,H3C所有交換機配置的model都是comware 解決方案: 1、找到compare.rb [rootoxidized model]# pwd /usr/local/lib/ruby/gems/3.1.0/gems/oxidized-0.29.1/lib/oxidized/model [rootoxidized model]# ll comware.rb -rw-r--…

mac本地安裝運行Redis-單機

記錄一下我以前用的連接服務器的跨平臺SSH客戶端。 因為還要準備畢設...... 服務器又過期了,只能把redis安裝下載到本地了。 目錄 1.github下載Redis 2.安裝homebrew 3.更新GCC 4.自行安裝Redis 5.通過 Homebrew 安裝 Redis 安裝地址:https://git…

C++學習之格斗小游戲綜合案例

C格斗游戲效果視頻 1.案例簡介 #include "broadSword.h" //構造函數 BroadSword::BroadSword() { FileManager fm; map<string, map<string, string>> mWeapon; fm.loadCSVData("Weapons.csv", mWeapon); //武器id string id …

《用Python+PyGame開發雙人生存游戲!源碼解析+完整開發思路分享》

導語? "你是否想過用Python開發一款可玩性高的雙人合作游戲&#xff1f;本文將分享如何從零開始實現一款類《吸血鬼幸存者》的生存射擊游戲&#xff01;包含完整源碼解析、角色系統設計、敵人AI邏輯等核心技術點&#xff0c;文末提供完整代碼包下載&#xff01;" 哈…

【理想解法學習筆記】

目錄 理想解法原理簡介算法步驟屬性值規范化方法代碼示例 理想解法 原理簡介 TOPSIS(Technique for Order Preference by Simi larity to IdealSolution)法是一種逼近理想解的排序方法。其基本的處理思路是&#xff1a;首先建立初始化決策矩陣&#xff0c;而后基于規范化后的初…

Linux基礎開發工具—vim

目錄 1、vim的概念 2、vim的常見模式 2.1 演示切換vim模式 3、vim命令模式常用操作 3.1 移動光標 3.2 刪除文字 3.3 復制 3.4 替換 4、vim底行模式常用命令 4.1 查找字符 5、vim的配置文件 1、vim的概念 Vim全稱是Vi IMproved&#xff0c;即說明它是Vi編輯器的增強…

Skyvern AI 實現 瀏覽器爬蟲+自動化工具

一、前言 本文Skyvern是一款功能強大的模擬瀏覽器自動化操作爬蟲軟件。它通過模擬人類在瀏覽器中的操作&#xff0c;實現對目標網站的自動化訪問、數據抓取和處理。Skyvern支持多種編程語言&#xff0c;用戶可根據需求編寫腳本&#xff0c;實現高效的數據采集。同時&#xff0c…

Spring Boot + MyBatis + MySQL:快速搭建CRUD應用

一、引言 1. 項目背景與目標 在現代Web開發中&#xff0c;CRUD&#xff08;創建、讀取、更新、刪除&#xff09;操作是幾乎所有應用程序的核心功能。本項目旨在通過Spring Boot、MyBatis和MySQL技術棧&#xff0c;快速搭建一個高效、簡潔的CRUD應用。我們將從零開始&#xff…

【Academy】OAuth 2.0 身份驗證漏洞 ------ OAuth 2.0 authentication vulnerabilities

OAuth 2.0 身份驗證漏洞 ------ OAuth 2.0 authentication vulnerabilities 1. 什么是 OAuth&#xff1f;2. OAuth 2.0 是如何工作的&#xff1f;3. OAuth 授權類型3.1 OAuth 范圍3.2 授權代碼授權類型3.3 隱式授權類型 4. OAuth 身份驗證4.1 識別 OAuth 身份驗證4.2 偵察OAuth…

C#常用的循環語句

在C#中&#xff0c;循環是一種控制結構&#xff0c;用于重復執行一組語句直到滿足特定條件。C#提供了幾種循環結構&#xff0c;包括for循環、while循環、do-while循環和foreach循環。每種循環都有其特定的用途和場景。下面我將逐一介紹這些循環的用法。 一、C#循環類型 1. fo…

C語言(23)

字符串函數 11.strstr函數 1.1函數介紹&#xff1a; 頭文件&#xff1a;string.h char *strstr ( const char * str1,const char *str2); 作用&#xff1a;在一個字符串&#xff08;str1&#xff09;中尋找另外一個字符串&#xff08;str2&#xff09;是否出現過 如果找到…

Vue3實戰學習(Vue3的基礎語法學習與使用(超詳細))(3)

目錄 &#xff08;1&#xff09;Vue3工程環境準備、項目基礎腳手架搭建詳細教程。(博客鏈接) &#xff08;2&#xff09;Vue3的基礎語法學習與使用。 &#xff08;1&#xff09;"{{}}"綁定數據。 <1>ref()函數定義變量——綁定數據。 <2>reactive({...})…

vtkDepthSortPolyData 根據相機視圖方向對多邊形數據進行排序

1. 作用 在 3D 渲染中&#xff0c;透明對象的渲染順序非常重要。如果透明對象的渲染順序不正確&#xff0c;可能會導致錯誤的視覺效果&#xff08;例如&#xff0c;遠處的透明對象遮擋了近處的透明對象&#xff09;。vtkDepthSortPolyData 通過對多邊形數據進行深度排序&#…

【2025力扣打卡系列】0-1背包 完全背包

堅持按題型打卡&刷&梳理力扣算法題系列&#xff0c;語言為python3&#xff0c;Day5 0-1背包【目標和】 有n個物品&#xff0c;第i個物品的體積為w[i], 價值為v[i]。每個物品至多選一個&#xff0c;求體積和不超過capacity時的最大價值和常見變形 至多裝capacity&#x…

MyBatis-Plus 分頁查詢接口返回值問題剖析

在使用 MyBatis-Plus 進行分頁查詢時,很多開發者會遇到一個常見的問題:當分頁查詢接口返回值定義為 Page<T> 時,執行查詢會拋出異常;而將返回值修改為 IPage<T> 時,分頁查詢卻能正常工作。本文將從 MyBatis-Plus 的分頁機制入手,詳細分析這一問題的根源,并提…