iT邦幫忙

2024 iThome 鐵人賽

DAY 25
1
JavaScript

不會 VueUse 而被提分手的我系列 第 25

D-25 useWebWorkerFn 解析與動機 - 研究替身

  • 分享至 

  • xImage
  •  

看似簡單的功能,實際上涉及到多執行緒的處理,它讓我理解了如何將耗時的任務交給背景去處理,而不影響主執行緒的運行。這就像是把繁瑣的事情交給另一個我去完成,讓我的思緒能專注於更重要的事。
https://ithelp.ithome.com.tw/upload/images/20241008/20162115pQsTz8qfkm.jpg

前言

useWebWorkerFn 是一個用於處理計算密集型任務的函式,利用了 Web Worker 的能力,將繁重的任務從主執行緒中分離出來,以避免阻塞 UI 反應時間,提高網頁應用程式的效能。

主要可以分為以下幾個步驟:

  1. Web Worker 建立與初始化
  2. 任務調度與通信
  3. 回調函式與結果處理
  4. 異常處理
  5. 清理與終止

我們逐一詳細解釋這些部分。

1. Web Worker 建立與初始化

Web Worker 是一個在背景執行的 JavaScript 程式,它獨立於主執行緒,適合用來處理大量計算工作,而不會影響主線程的 UI 響應。

useWebWorkerFn 中,當調用者傳遞一個需要在背景執行的函式時,這個函式會被封裝到 Web Worker 中:

const worker = new Worker(URL.createObjectURL(new Blob([`(${workerFn})()`])));

這段程式碼利用了 BlobURL.createObjectURL 來動態建立一個 Web Worker,將用戶傳入的函式 (workerFn) 轉化成可以在 Worker 中執行的代碼。

2. 任務調度與通信

Web Worker 的運行是異步的,且無法直接訪問 DOM。這意味著主線程和 Web Worker 必須通過消息傳遞來進行通信。useWebWorkerFn 通過以下方式進行通信:

worker.postMessage(data);
worker.onmessage = (event) => {
  state.result = event.data;
  state.error = null;
};

  • postMessage:主線程使用 postMessage 將需要處理的資料發送到 Worker 中。
  • onmessage:當 Worker 完成處理任務後,通過 onmessage 將結果回傳給主線程,並更新狀態。

3. 回調函式與結果處理

useWebWorkerFn 通常會管理一些關鍵狀態,如任務是否執行中、結果和錯誤等。這些狀態由 refreactive 來管理,使外部組件能夠對狀態變化作出反應。

const state = reactive({
  result: null,
  error: null,
  isRunning: false,
});

當任務開始時,isRunning 設置為 true,當 Worker 回傳結果時,則更新結果並將 isRunning 設置為 false。這樣一來,外部組件便可以根據 isRunning 來顯示進度指示器,或根據 result 來更新顯示的內容。

4. 異常處理

在處理大量計算任務時,異常可能會發生,例如數據格式不正確或運算溢出。useWebWorkerFn 通過捕捉 Worker 的 onerror 事件來處理這些情況:

worker.onerror = (error) => {
  state.error = error;
  state.isRunning = false;
};

這段程式碼確保當 Worker 運行中發生錯誤時,將錯誤資訊存入 state.error,同時將 isRunning 設置為 false,以便 UI 能夠正確地反映當前狀態。

5. 清理與終止

Web Worker 的運行會佔用系統資源,因此在不需要使用 Web Worker 時,我們應及時終止它:

function terminate() {
  worker.terminate();
  state.isRunning = false;
}

terminate 函式用於終止 Web Worker 的執行,釋放系統資源。useWebWorkerFn 通常會在組件卸載時調用該函式,以確保不會遺留多餘的資源占用。

工作流程

  1. Web Worker 建立:根據用戶提供的函式建立一個 Web Worker。
  2. 調度與通信:使用 postMessage 向 Worker 傳遞資料,並監聽 onmessage 以接收處理結果。
  3. 狀態管理:通過 reactive 管理計算任務的狀態,包括是否執行中、結果和錯誤信息等。
  4. 錯誤處理:捕捉 Worker 運行中的錯誤並更新狀態。
  5. 清理資源:在任務完成或組件卸載時終止 Worker,釋放資源。

https://ithelp.ithome.com.tw/upload/images/20241008/201621152XN61OeDRH.png

原始碼部分解釋

1. 型別定義

export interface UseWebWorkerOptions {
  immediate?: boolean; // 是否在建立時立即執行
  timeout?: number; // 任務的最大執行時間
}

這裡定義了 useWebWorkerFn 的選項介面:

  • immediate:是否在建立時立即執行任務。
  • timeout:設定最大允許的任務執行時間,以避免 Worker 過久佔用資源。

2. useWebWorkerFn 函式

export function useWebWorkerFn(workerFn: Function, options: UseWebWorkerOptions = {}) {
  const state = reactive({
    result: null,
    error: null,
    isRunning: false,
  });

  function run(data: any) {
    // 任務執行邏輯
  }

  function terminate() {
    // 終止 Web Worker
  }

  return {
    run,
    terminate,
    ...toRefs(state),
  };
}

useWebWorkerFn 建立了一個 Worker 並返回三個主要函式和屬性:

  • run:執行計算任務。
  • terminate:終止 Worker。
  • resulterrorisRunning:返回狀態的計算屬性,用於外部監聽和顯示。

總結

useWebWorkerFn 透過將繁重的計算工作移交給 Web Worker 來提高網頁應用的響應性。它在主線程和 Worker 之間通過消息傳遞進行通信,並管理任務狀態和錯誤處理,提供了一個簡潔的 API 來處理高效能的非同步計算。

這個函式結合 Vue 的響應式系統和 Web Worker 的並行計算能力,大大簡化了使用 Worker 的流程,減少每次翻文件的時間。。

如果有任何錯誤或者需要補充的部分,請隨時告訴我!


上一篇
D-24 useWebWorkerFn 文件說明與範例 - 忍術替身術
下一篇
D-26 useQRCode 文件說明與範例 - 會員或載具嗎?
系列文
不會 VueUse 而被提分手的我30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言