Web Worker i TypeScript

Web Worker i TypeScript

Denne artikel forklarer Web Workers i TypeScript.

Du kan lære om konceptet Web Workers og få tips til brug med eksempler.

YouTube Video

Worker i TypeScript

I TypeScript er en Worker en mekanisme til at udføre processer i baggrunden, adskilt fra hovedtråden, ved at udnytte JavaScript Web Workers API'et. Dette gør det muligt at udføre tunge beregninger og asynkrone opgaver uden at påvirke brugerfladens funktion.

En Worker kører parallelt med hovedtråden (UI-tråden) og kan udveksle data mellem tråde via beskeder. Selv i TypeScript kan du bruge Worker samtidig med at skrive typesikker kode.

Grundlæggende brug af Worker

  1. Opret en Worker

    Opret en Worker-instans og udfør det specificerede script. Normalt er scriptet defineret i en separat fil.

  2. Beskedudveksling

    Send og modtag beskeder mellem hovedtråden og Worker-tråden ved hjælp af postMessage og onmessage.

Eksempel: Grundlæggende implementering af Worker

  1. worker.ts: Script til 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: Script til at bruge Worker i hovedtrå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 dette eksempel kører worker.ts i en separat tråd, beregner summen af num1 og num2 og returnerer den til hovedtråden. Hovedtråden modtager resultatet og skriver det til konsollen.
  • Når du angiver type: 'module', fortolkes Worker-skriptet som et ES-modul, hvilket gør det muligt at bruge import og export. Dette gør det muligt at håndtere modulstrukturer uden at bruge den traditionelle importScripts().

Punkter at overveje ved brug af Workers i TypeScript

Tilføjelse af typedefinitioner

I TypeScript kan du definere datatyper for at sikre typesikker interaktion under afsendelse og modtagelse af beskeder.

 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);
  • Ved at angive typeparameteren for MessageEvent kan du tydeligt definere, hvilken type data der skal modtages. Dette muliggør udveksling af data med typesikkerhed.

Opsætning af Webpack eller Vite

Når du bruger Worker i TypeScript, kan det være nødvendigt med bundlere som Webpack eller Vite. Ved at bruge disse værktøjer kan du korrekt samle Worker-scriptet og gøre det tilgængeligt fra hovedtråden.

For eksempel, når du bruger Vite, skal du bruge import.meta.url til korrekt at importere Worker.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
  • Dette sikrer, at det samlede Worker-script indlæses korrekt og muliggør behandling ved hjælp af Worker.

Overvejelser om beskedudveksling og samtidighed

  1. Data Kopiering

    Når der sendes og modtages beskeder mellem hovedtråden og Worker-tråden, bliver data kopieret. Når du arbejder med komplekse data som objekter, skal effektiviteten overvejes. Hyppig udveksling af store datamængder kan forringe ydeevnen.

  2. Overførbare Objekter

    Nogle objekter, såsom ArrayBuffer, kaldes Transferable objekter. Transferable objekter kan overføres til Workeren i stedet for at blive kopieret under beskedudveksling. Dette gør det muligt at undgå overhead ved 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)
  • Ved at angive [buffer] som det andet argument til worker.postMessage(), overføres buffer til Workeren i stedet for at blive kopieret.

  • Herefter bliver buffer i hovedtråden tom (med byteLength 0) og kan kun bruges af Workeren.

Afslutning af en Worker

Worker bør afsluttes efter brug for at minimere hukommelsesforbrug. Du kan afslutte en Worker ved at bruge terminate-metoden.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
  • Denne kode afslutter Workeren ved at bruge terminate-metoden.

Undtagelseshåndtering i Worker

Hvis der opstår en fejl i en Worker, kan du håndtere fejlen ved hjælp af onerror-begivenheden.

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};
  • Denne kode opfanger og håndterer fejl, der opstår inde i Workeren, ved hjælp af onerror-hændelsen.

Sammendrag

Ved at bruge Worker i TypeScript kan du udføre tunge opgaver i baggrunden og samtidig holde hovedtråden glidende. Ved at anvende typedefinitioner kan beskedudveksling også udføres på en type-sikker måde. Ved at være opmærksom på dataudveksling og trådhåndtering kan du opnå ydeevneforbedringer og effektiv samtidighed.

Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.

YouTube Video