Web Worker w TypeScript
Ten artykuł wyjaśnia Web Workery w TypeScript.
Możesz dowiedzieć się o koncepcji Web Workerów
oraz poznać różne wskazówki dotyczące ich użycia wraz z przykładami.
YouTube Video
Worker w TypeScript
W TypeScript, Worker
to mechanizm umożliwiający wykonywanie obliczeń w tle, oddzielnie od głównego wątku, wykorzystując API Web Workerów JavaScript. Pozwala to na wykonywanie ciężkich obliczeń i zadań asynchronicznych bez wpływu na działanie interfejsu użytkownika.
Worker
działa równolegle z głównym wątkiem (wątkiem UI) i może wymieniać dane między wątkami za pomocą wiadomości. Nawet w TypeScript można używać Worker
, pisząc kod z bezpiecznym typowaniem.
Podstawowe użycie Workera
-
Tworzenie Workera
Utwórz instancję
Worker
i uruchom określony skrypt. Zwykle skrypt jest definiowany w osobnym pliku. -
Wymiana wiadomości
Wysyłaj i odbieraj wiadomości między głównym wątkiem a wątkiem
Worker
za pomocąpostMessage
ionmessage
.
Przykład: Podstawowa implementacja Workera
- worker.ts: Skrypt dla Workera
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: Skrypt do użycia Workera w głównym wątku
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
- W tym przykładzie
worker.ts
działa w osobnym wątku, oblicza sumęnum1
inum2
, a następnie zwraca ją do głównego wątku. Główny wątek odbiera wynik i wyświetla go w konsoli. - Gdy określisz
type: 'module'
, skrypt Workera jest interpretowany jako moduł ES, co pozwala na używanieimport
iexport
. Pozwala to obsługiwać struktury modułów bez użycia tradycyjnej funkcjiimportScripts()
.
Punkty do rozważenia przy używaniu Workerów w TypeScript
Dodawanie definicji typów
W TypeScript zdefiniuj typy danych, aby zapewnić bezpieczną dla typów interakcję podczas wysyłania i odbierania wiadomości.
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);
- Określając parametr typu
MessageEvent
, można jasno zdefiniować typ danych do odbioru. Pozwala to na wymianę danych z zachowaniem bezpieczeństwa typów.
Konfiguracja Webpack lub Vite
Podczas korzystania z Worker
w TypeScript może być wymagane użycie narzędzi do bundlowania, takich jak Webpack
lub Vite
. Używając tych narzędzi, możesz odpowiednio zbundlować skrypt Worker
i udostępnić go z głównego wątku.
Na przykład, używając Vite
, użyj import.meta.url
, aby poprawnie zaimportować Worker
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
- Gwarantuje to poprawne załadowanie zbundlowanego skryptu
Worker
, umożliwiając przetwarzanie z wykorzystaniemWorker
.
Uwagi dotyczące przesyłania wiadomości i współbieżności
-
Kopiowanie danych
Podczas wysyłania i odbierania wiadomości między głównym wątkiem a wątkiem
Worker
dane są kopiowane. Przy pracy ze złożonymi danymi, takimi jak obiekty, należy wziąć pod uwagę wydajność. Częste wymienianie dużych ilości danych może obniżyć wydajność. -
Obiekty
Transferable
Niektóre obiekty, takie jak
ArrayBuffer
, są nazywane obiektamiTransferable
(przenaszalnymi). ObiektyTransferable
mogą być przenoszone do Workera zamiast kopiowane podczas przesyłania wiadomości. Pozwala to uniknąć obciążenia związanego z kopiowaniem danych.
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)
-
Przekazując
[buffer]
jako drugi argument doworker.postMessage()
, bufor zostaje przeniesiony do Workera, zamiast być kopiowany. -
Po tym bufor w głównym wątku staje się pusty (o
byteLength
równym 0) i może być używany tylko przez Workera.
Zakończenie Worker
a
Worker
powinien zostać zakończony po użyciu, aby zminimalizować zużycie pamięci. Worker
a można zakończyć, używając metody terminate
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
- Ten kod kończy działanie Workera przez użycie metody
terminate
.
Obsługa wyjątków w Worker
ze
Jeśli w Worker
ze wystąpi błąd, możesz obsłużyć go za pomocą zdarzenia onerror
.
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};
- Ten kod wychwytuje i obsługuje błędy występujące w Workerze przy użyciu zdarzenia
onerror
.
Podsumowanie
Korzystając z Worker
w TypeScript, możesz wykonywać ciężkie zadania w tle, zachowując płynność wątku głównego. Wykorzystując definicje typów, wymiana wiadomości może odbywać się w sposób typowany. Zwracając uwagę na wymianę danych i zarządzanie wątkami, możesz osiągnąć poprawę wydajności i efektywną współbieżność.
Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.