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
-
Skapa en Worker
Skapa en
Worker
-instans och kör det angivna skriptet. Vanligtvis definieras skriptet i en separat fil. -
Meddelandeutbyte
Skicka och ta emot meddelanden mellan huvudtråden och
Worker
-tråden med hjälp avpostMessage
ochonmessage
.
Exempel: Grundläggande Worker-implementation
- 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};
- 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 avnum1
ochnum2
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ändaimport
ochexport
. Detta gör att du kan hantera modulstrukturer utan att använda traditionellaimportScripts()
.
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 avWorker
.
Överväganden för meddelandehantering och samtidighet
-
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. -
Transferable
-objektVissa objekt, såsom
ArrayBuffer
, kallas förTransferable
-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 tillworker.postMessage()
, överförsbuffer
till Workern istället för att kopieras. -
Efter detta blir
buffer
på huvudtråden tom (medbyteLength
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.