Web Worker i TypeScript

Web Worker i TypeScript

Den här artikeln förklarar Web Workers i TypeScript.

Du kan lära dig om konceptet Web Workers och olika användningstips med exempel.

YouTube Video

Worker i TypeScript

I TypeScript är en Worker en mekanism för att utföra bearbetningar i bakgrunden, separat från huvudtråden, med hjälp av JavaScript Web Workers API. Detta möjliggör tunga beräkningar och asynkrona uppgifter utan att påverka användargränssnittets funktion.

En Worker arbetar parallellt med huvudtråden (UI-tråden) och kan utbyta data mellan trådar via meddelanden. Även i TypeScript kan du använda Worker när du skriver typesäker kod.

Grundläggande användning av Worker

  1. Skapa en Worker

    Skapa en Worker-instans och kör det angivna skriptet. Vanligtvis definieras skriptet i en separat fil.

  2. Meddelandeutbyte

    Skicka och ta emot meddelanden mellan huvudtråden och Worker-tråden med hjälp av postMessage och onmessage.

Exempel: Grundläggande Worker-implementation

  1. worker.ts: Skript för Worker
1// worker.ts
2self.onmessage = (event) => {
3    const data = event.data;
4    const result = data.num1 + data.num2;
5    self.postMessage(result); // Return the result to the main thread
6};
  1. main.ts: Skript för att använda Worker i huvudtråden
 1// main.ts
 2const worker = new Worker(
 3    new URL('./worker.ts', import.meta.url),
 4    { type: 'module' }
 5);
 6
 7worker.onmessage = (event) => {
 8    console.log("Result from worker:", event.data); // Receive message from the worker
 9};
10
11worker.postMessage({ num1: 10, num2: 20 }); // Send message to the worker
  • I detta exempel körs worker.ts i en separat tråd, beräknar summan av num1 och num2 och returnerar detta till huvudtråden. Huvudtråden tar emot resultatet och skriver ut det till konsolen.
  • När du anger type: 'module' tolkas Worker-skriptet som en ES-modul, vilket gör att du kan använda import och export. Detta gör att du kan hantera modulstrukturer utan att använda traditionella importScripts().

Viktiga punkter att tänka på när man använder Workers i TypeScript

Lägga till typedefinitioner

I TypeScript definierar du datatyper för att säkerställa typesäker interaktion vid sändning och mottagning av meddelanden.

 1// Define data types
 2interface WorkerData {
 3    num1: number;
 4    num2: number;
 5}
 6
 7interface WorkerResult {
 8    result: number;
 9}
10
11// worker.ts
12self.onmessage = (event: MessageEvent<WorkerData>) => {
13    const data = event.data;
14    const result = data.num1 + data.num2;
15    const message: WorkerResult = { result };
16    self.postMessage(message); // Send the result in a type-safe manner
17};
18
19// main.ts
20const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
21
22// Type the event from the worker
23worker.onmessage = (event: MessageEvent<WorkerResult>) => {
24  console.log("Result from worker:", event.data); // event.data is number
25};
26
27// Send typed data to the worker
28const message: WorkerData = { num1: 10, num2: 20 };
29worker.postMessage(message);
  • Genom att specificera typparametern för MessageEvent kan du tydligt definiera vilken typ av data som ska tas emot. Detta möjliggör typesäkert datautbyte.

Konfigurera Webpack eller Vite

När du använder Worker i TypeScript kan det krävas bundlare som Webpack eller Vite. Genom att använda dessa verktyg kan du korrekt samla Worker-skriptet och göra det tillgängligt från huvudtråden.

Till exempel, när du använder Vite, använd import.meta.url för att korrekt importera Worker.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
  • Detta säkerställer att det samlade Worker-skriptet laddas korrekt, vilket möjliggör bearbetning med hjälp av Worker.

Överväganden för meddelandehantering och samtidighet

  1. Dataropiering

    När meddelanden skickas och tas emot mellan huvudtråden och Worker-tråden kopieras data kopieras. Vid hantering av komplex data, som objekt, behöver effektivitet övervägas. Att ofta utbyta stora mängder data kan försämra prestandan.

  2. Transferable-objekt

    Vissa objekt, såsom ArrayBuffer, kallas för Transferable-objekt. Transferable-objekt kan överföras till Workern istället för att kopieras vid meddelandeöverföring. Detta gör att du kan undvika den extra belastningen av datakopiering.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3const buffer = new ArrayBuffer(1024);
4worker.postMessage(buffer, [buffer]); // Transfer ownership to the Worker
5
6console.log(buffer.byteLength); // 0 (ownership moved)
  • Genom att skicka [buffer] som det andra argumentet till worker.postMessage(), överförs buffer till Workern istället för att kopieras.

  • Efter detta blir buffer på huvudtråden tom (med byteLength 0) och kan endast användas av Workern.

Avsluta en Worker

Worker bör avslutas efter användning för att minimera minnesförbrukningen. Du kan avsluta en Worker genom att använda terminate-metoden.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
  • Denna kod avslutar Workern genom att använda metoden terminate.

Undantagshantering i Worker

Om ett fel uppstår inom en Worker kan du hantera felet med hjälp av onerror-händelsen.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3worker.onerror = (error) => {
4    console.error("Error in Worker:", error.message);
5};
  • Denna kod fångar och hanterar fel som uppstår inne i Workern med hjälp av händelsen onerror.

Sammanfattning

Genom att använda Worker i TypeScript kan du köra tunga uppgifter i bakgrunden samtidigt som huvudtråden hålls jämn. Genom att använda typdefinitioner kan meddelandeutbyten också göras på ett typsäkert sätt. Genom att uppmärksamma datautbyte och trådhantering kan du uppnå prestandaförbättringar och effektiv samtidighet.

Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.

YouTube Video