首頁  >  文章  >  web前端  >  使用 Web Workers 在 JS 中實作多執行緒

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

王林
王林原創
2024-08-16 06:18:02292瀏覽

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

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

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

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

另一方面,

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

2. Web Workers 簡介

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

  • 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內部,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 });
        }
    }
};

此程式碼示範如何向工作執行緒發送訊息並在主執行緒中接收獲取的資料。

MultiThreading In JS using Web Workers

完整程式碼請存取代碼

MultiThreading In JS using Web Workers

5. Web Workers 的限制

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

  • 無法存取 DOM:Workers 無法直接操作 DOM。更新 UI 需要與主執行緒通訊。
  • 資源消耗:過度使用 Web Worker 可能會導致記憶體使用率過高,因為每個 Worker 都需要額外的資源才能獨立運作。

以上是使用 Web Workers 在 JS 中實作多執行緒的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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