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

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

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

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]刪除
最新教學 更多>
  • 如何使用Python有效地以相反順序讀取大型文件?
    如何使用Python有效地以相反順序讀取大型文件?
    在python 中,如果您使用一個大文件,並且需要從最後一行讀取其內容,則在第一行到第一行,Python的內置功能可能不合適。這是解決此任務的有效解決方案:反向行讀取器生成器 == ord('\ n'): 緩衝區=緩衝區[:-1] ...
    程式設計 發佈於2025-04-05
  • 如何將PANDAS DataFrame列轉換為DateTime格式並按日期過濾?
    如何將PANDAS DataFrame列轉換為DateTime格式並按日期過濾?
    將pandas dataframe列轉換為dateTime格式示例:使用column(mycol)包含以下格式的以下dataframe,以自定義格式:})指定的格式參數匹配給定的字符串格式。轉換後,MyCol列現在將包含DateTime對象。 date date filtering > = ...
    程式設計 發佈於2025-04-05
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-04-05
  • 如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    從python import codecs import codecs import codecs 導入 text = codecs.decode('這狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#帶有...
    程式設計 發佈於2025-04-05
  • 如何將來自三個MySQL表的數據組合到新表中?
    如何將來自三個MySQL表的數據組合到新表中?
    mysql:從三個表和列的新表創建新表 答案:為了實現這一目標,您可以利用一個3-way Join。 選擇p。 *,d.content作為年齡 來自人為p的人 加入d.person_id = p.id上的d的詳細信息 加入T.Id = d.detail_id的分類法 其中t.taxonomy ...
    程式設計 發佈於2025-04-05
  • 我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    將我的加密庫從mcrypt升級到openssl 問題:是否可以將我的加密庫從McRypt升級到OpenSSL?如果是這樣,如何? 答案:是的,可以將您的Encryption庫從McRypt升級到OpenSSL。 可以使用openssl。 附加說明: [openssl_decrypt()函數要求...
    程式設計 發佈於2025-04-05
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-04-05
  • 如何在無序集合中為元組實現通用哈希功能?
    如何在無序集合中為元組實現通用哈希功能?
    在未訂購的集合中的元素要糾正此問題,一種方法是手動為特定元組類型定義哈希函數,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    程式設計 發佈於2025-04-05
  • 為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    使用php dateTime修改月份:發現預期的行為在使用PHP的DateTime類時,添加或減去幾個月可能並不總是會產生預期的結果。正如文檔所警告的那樣,“當心”這些操作的“不像看起來那樣直觀。 考慮文檔中給出的示例:這是內部發生的事情: 現在在3月3日添加另一個月,因為2月在2001年只有2...
    程式設計 發佈於2025-04-05
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-04-05
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-04-05
  • 如何使用Regex在PHP中有效地提取括號內的文本
    如何使用Regex在PHP中有效地提取括號內的文本
    php:在括號內提取文本在處理括號內的文本時,找到最有效的解決方案是必不可少的。一種方法是利用PHP的字符串操作函數,如下所示: 作為替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式來搜索特...
    程式設計 發佈於2025-04-05
  • 如何處理PHP文件系統功能中的UTF-8文件名?
    如何處理PHP文件系統功能中的UTF-8文件名?
    在PHP的Filesystem functions中處理UTF-8 FileNames 在使用PHP的MKDIR函數中含有UTF-8字符的文件很多flusf-8字符時,您可能會在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    程式設計 發佈於2025-04-05
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-04-05
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-04-05

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

Copyright© 2022 湘ICP备2022001581号-3