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ę
Workeri 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
Workerza pomocąpostMessageionmessage.
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.tsdziała w osobnym wątku, oblicza sumęnum1inum2, 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żywanieimportiexport. 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
Workerdane 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
TransferableNiektóre obiekty, takie jak
ArrayBuffer, są nazywane obiektamiTransferable(przenaszalnymi). ObiektyTransferablemogą 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
byteLengthrównym 0) i może być używany tylko przez Workera.
Zakończenie Workera
Worker powinien zostać zakończony po użyciu, aby zminimalizować zużycie pamięci. Workera 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 Workerze
Jeśli w Workerze 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.