」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 Web Workers 在 JS 中實作多執行緒

使用 Web Workers 在 JS 中實作多執行緒

發佈於2024-08-20
瀏覽:462

Web Worker:一種在與目前主(視窗)執行緒不同的執行緒中在背景執行腳本的方法。

  1. Web Workers 與使用 event_loop 的非同步
  2. 網路工作者簡介
  3. 如何創建網路工作者
  4. 例如網路工作者
  5. Web Workers 的限制
  6. Web Workers 中的非同步操作

1. Web Workers 與使用事件循環的非同步操作

JavaScript通常透過將任務放入對應的佇列(巨集任務佇列、微任務佇列)來處理非同步操作,事件循環不斷檢查這些佇列,並在任務準備好執行時將其推送到呼叫堆疊中。這種方法確保非阻塞執行,但仍然在單一執行緒上運行所有內容。

Web Workers 另一方面,允許腳本在完全獨立的執行緒中運行,具有自己的呼叫堆疊、非同步佇列和事件循環。這種分離可以防止主執行緒被繁重的運算或長時間運行的任務阻塞,因為工作執行緒獨立運行。

2. Web Workers 簡介

Web Worker 在與主視窗上下文不同的上下文中執行腳本,從而實現 Web 應用程式中的並行性。 Web Worker API 提供了幾種類型的工作人員:

  • Dedicated Workers:由單一腳本使用,非常適合從主執行緒卸載任務。
  • 共享工作執行緒:可由在不同上下文(例如,不同視窗或 iframe)中執行的多個腳本存取。
  • Service Workers:作為 Web 應用程式、瀏覽器和網路之間的代理伺服器運行,提供離線支援和快取等功能。

本文重點介紹專用工作人員,這是最容易實現且最常用的。

3. 如何建立 Web Worker

要建立Web Worker,您可以使用以下關鍵方法:

  • new Worker():建立新worker的建構子。
  • postMessage():從主執行緒向工作執行緒傳送訊息,反之亦然。
  • onmessage:設定用於處理worker收到的訊息的回呼函數。
  • terminate():立即停止工作執行緒。

4. 簡單範例

讓我們創建一個工作程序來從 API 獲取數據,特別是從 Dog CEO API 獲取狗圖像。

4.1 工人代碼

這裡是worker腳本的實作。請注意,在worker內部,self用於引用全域上下文:

if (window.Worker) {
    const worker = new Worker("/src/worker.js");
        worker.postMessage({ 
            operation: "get_dog_imgs",
            url: "https://dog.ceo/api/breeds/image/random", 
            count: 5   //number of photos
        });
        worker.onmessage = (e) => {
        console.log(e.data);
        if (e && e.data) {
            setdata((old) => [...old, e.data]); // update react state
            showCallStack(); // function to show the callstack 
        }
    };
    worker.onerror = (e) => {
        console.log(e);
    };
}

在此程式碼中,worker 偵聽訊息 (onmessage) 並根據計數指定多次從給定 URL 取得資料。

這是工作者內部的呼叫堆疊:

MultiThreading In JS using Web Workers

4.2 客戶端程式碼

主執行緒像這樣使用worker:

self.onmessage = (event) => {
    const data = event.data;
    if (data && data.url && data.count) {
        fetchFromUrls(data.url, data.count);
    }
}
// fetch single data 
const fetchdata = async (url) => {
    const res = await self.fetch(url);
    return await res.json();
};

const fetchFromUrls = async (url, count) => {
    showCallStack(); // showing the callstack of the worker 
    for (const i of new Array(count).fill(0)) {
        let data = await fetchdata(url);
        if (data && data.message) {
            self.postMessage({ type: "img", data: data.message });
        }
    }
};

這段程式碼示範如何向worker發送訊息並在主執行緒中接收所獲取的資料。

MultiThreading In JS using Web Workers

完整代碼請訪問代碼

MultiThreading In JS using Web Workers

5. Web Workers 的限制

雖然 Web Worker 在與主視窗執行緒不同的執行緒中運行,但它們具有一定的限制:

  • 無法存取 DOM:Workers 無法直接操作 DOM。更新 UI 需要與主執行緒通訊。
  • 資源消耗:過度使用 Web Worker 可能會導致記憶體使用率過高,因為每個 Worker 都需要額外的資源才能獨立運作。
版本聲明 本文轉載於:https://dev.to/anasmustafa123/multithreading-in-js-1llg?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何干淨地刪除匿名JavaScript事件處理程序?
    如何干淨地刪除匿名JavaScript事件處理程序?
    刪除匿名事件偵聽器將匿名事件偵聽器添加到元素中會提供靈活性和簡單性,但是當要刪除它們時,可以構成挑戰,而無需替換元素本身就可以替換一個問題。 element? element.addeventlistener(event,function(){/在這里工作/},false); 要解決此問題,請考...
    程式設計 發佈於2025-06-10
  • 如何修復\“常規錯誤:2006 MySQL Server在插入數據時已經消失\”?
    如何修復\“常規錯誤:2006 MySQL Server在插入數據時已經消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    程式設計 發佈於2025-06-10
  • 在JavaScript中如何並發運行異步操作並正確處理錯誤?
    在JavaScript中如何並發運行異步操作並正確處理錯誤?
    同意操作execution 在執行asynchronous操作時,相關的代碼段落會遇到一個問題,當執行asynchronous操作:此實現在啟動下一個操作之前依次等待每個操作的完成。要啟用並發執行,需要進行修改的方法。 第一個解決方案試圖通過獲得每個操作的承諾來解決此問題,然後單獨等待它們: c...
    程式設計 發佈於2025-06-10
  • PHP未來:適應與創新
    PHP未來:適應與創新
    PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。 引言在編程世界中,PHP一直是網頁開發的中流砥柱。作為一個從1994年就開始發展...
    程式設計 發佈於2025-06-10
  • 反射動態實現Go接口用於RPC方法探索
    反射動態實現Go接口用於RPC方法探索
    在GO 使用反射來實現定義RPC式方法的界面。例如,考慮一個接口,例如:鍵入myService接口{ 登錄(用戶名,密碼字符串)(sessionId int,錯誤錯誤) helloworld(sessionid int)(hi String,錯誤錯誤) } 替代方案而不是依靠反射...
    程式設計 發佈於2025-06-10
  • 如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    從python import codecs import codecs import codecs 導入 text = codecs.decode('這狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#帶有...
    程式設計 發佈於2025-06-10
  • Python中嵌套函數與閉包的區別是什麼
    Python中嵌套函數與閉包的區別是什麼
    嵌套函數與python 在python中的嵌套函數不被考慮閉合,因為它們不符合以下要求:不訪問局部範圍scliables to incling scliables在封裝範圍外執行範圍的局部範圍。 make_printer(msg): DEF打印機(): 打印(味精) ...
    程式設計 發佈於2025-06-10
  • Android如何向PHP服務器發送POST數據?
    Android如何向PHP服務器發送POST數據?
    在android apache httpclient(已棄用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    程式設計 發佈於2025-06-10
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-06-10
  • Python讀取CSV文件UnicodeDecodeError終極解決方法
    Python讀取CSV文件UnicodeDecodeError終極解決方法
    在試圖使用已內置的CSV模塊讀取Python中時,CSV文件中的Unicode Decode Decode Decode Decode decode Error讀取,您可能會遇到錯誤的錯誤:無法解碼字節 在位置2-3中:截斷\ uxxxxxxxx逃脫當CSV文件包含特殊字符或Unicode的路徑逃...
    程式設計 發佈於2025-06-10
  • CSS強類型語言解析
    CSS強類型語言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    程式設計 發佈於2025-06-10
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-06-10
  • JavaScript計算兩個日期之間天數的方法
    JavaScript計算兩個日期之間天數的方法
    How to Calculate the Difference Between Dates in JavascriptAs you attempt to determine the difference between two dates in Javascript, consider this s...
    程式設計 發佈於2025-06-10
  • 在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    程式設計 發佈於2025-06-10
  • Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    在ASP.NET async void void async void void void void void的設計無需返回asynchroncon而無需返回任務對象。他們在執行過程中增加未償還操作的計數,並在完成後減少。在某些情況下,這種行為可能是有益的,例如未期望或明確預期操作結果的火災和...
    程式設計 發佈於2025-06-10

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3