Web Worker w TypeScript

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

  1. Tworzenie Workera

    Utwórz instancję Worker i uruchom określony skrypt. Zwykle skrypt jest definiowany w osobnym pliku.

  2. Wymiana wiadomości

    Wysyłaj i odbieraj wiadomości między głównym wątkiem a wątkiem Worker za pomocą postMessage i onmessage.

Przykład: Podstawowa implementacja Workera

  1. 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};
  1. 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 i num2, 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żywanie import i export. Pozwala to obsługiwać struktury modułów bez użycia tradycyjnej funkcji importScripts().

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 wykorzystaniem Worker.

Uwagi dotyczące przesyłania wiadomości i współbieżności

  1. 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ść.

  2. Obiekty Transferable

    Niektóre obiekty, takie jak ArrayBuffer, są nazywane obiektami Transferable (przenaszalnymi). Obiekty Transferable 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 do worker.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 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.

YouTube Video