Programiści JavaScript są przyzwyczajeni do udawania równoległości, ale istnieje sposób na osiągnięcie prawdziwej równoległości, którego powinieneś teraz używać.

JavaScript może mieć problemy z zadaniami wymagającymi dużej wydajności, ponieważ jest to język jednowątkowy. Korzystając z równoległości, możesz osiągnąć wielowątkowe wykonywanie w JavaScript oraz poprawić wydajność i szybkość reakcji nowoczesnych aplikacji internetowych.

Równoległość w programowaniu JavaScript

Równoległość ma kluczowe znaczenie w nowoczesnych komputerach dla poprawy wydajności i skalowalności. Czyni to poprzez efektywne wykorzystanie dostępnych zasobów.

Powszechną techniką stosowaną do osiągnięcia równoległości w programowaniu jest wielowątkowość. Wątek JavaScript jest jednak systemem jednowątkowym i może obsłużyć tylko jedno zadanie na raz. Oznacza to, że nie jest zaznajomiony z wykonywaniem programów równoległych.

JavaScript podrabia programowanie równoległe

Powszechnym błędnym przekonaniem na temat równoległości jest to, że można to osiągnąć za pomocą

instagram viewer
techniki programowania asynchronicznego jak asynchronizacja/oczekiwanie, wywołania zwrotne i obietnice:

// Funkcja asynchronizacji/oczekiwania, która symuluje żądanie sieciowe
asynchronicznyfunkcjonowaćpobierz dane() {
konst odpowiedź = czekać na aportować();
konst dane = czekać na odpowiedź.json();
powrót dane;
}

// Funkcja wywołania zwrotnego, która rejestruje pobrane dane w konsoli
funkcjonowaćdane dziennika(dane) {
konsola.log (dane);
}

// Metoda Promise.all() wykonująca równolegle wiele obietnic
Obietnica.Wszystko([
pobierzDane(),
pobierzDane(),
]).Następnie((wyniki) => {
konsola.log (wyniki);
});

// Wywołaj funkcję fetchData i przekaż funkcję logData jako wywołanie zwrotne
fetchData().then (logData);

Techniki te w rzeczywistości nie wykonują kodu równolegle. JavaScript wykorzystuje pętlę zdarzeń do naśladowania programowania równoległego w swoim projekcie jednowątkowym.

Pętla zdarzeń jest podstawową częścią środowiska uruchomieniowego JavaScript. Umożliwia wykonywanie operacji asynchronicznych, takich jak żądania sieciowe, w tle bez blokowania głównego pojedynczego wątku.

Pętla zdarzeń stale sprawdza nowe zdarzenia lub zadania w kolejce i wykonuje je sekwencyjnie jedno po drugim. Ta technika pozwala JavaScriptowi osiągnąć współbieżność i teoretyczną równoległość.

Współbieżność vs. Równoległość

Współbieżność i równoległość są często źle rozumiane i stosowane zamiennie w świecie JavaScript.

Współbieżność w JavaScript odnosi się do możliwości wykonywania wielu zadań poprzez nakładanie się wykonywania zadań. Gdzie jedno zadanie może rozpocząć się przed zakończeniem innego, ale zadania nie mogą się rozpocząć ani zakończyć jednocześnie. Dzięki temu JavaScript może wydajnie obsługiwać operacje, takie jak pobieranie danych z interfejsu API REST lub odczytywanie plików, bez blokowania głównego wątku wykonawczego.

Z drugiej strony równoległość odnosi się do możliwości wykonywania wielu zadań jednocześnie w wielu wątkach. Te wątki w tle mogą wykonywać zadania niezależnie i jednocześnie. Otwiera to możliwości osiągnięcia prawdziwej równoległości w aplikacjach JavaScript.

Aplikacje JavaScript mogą osiągnąć prawdziwą równoległość poprzez korzystanie z Web Workerów.

Pracownicy sieci Web wprowadzają równoległość do JavaScript

Web Workers to funkcja nowoczesnych przeglądarek internetowych, która umożliwia uruchamianie kodu JavaScript w wątkach tła, niezależnie od głównego wątku wykonawczego. W przeciwieństwie do głównego wątku, który obsługuje interakcje użytkownika i aktualizacje interfejsu użytkownika. Web Worker byłby przeznaczony do wykonywania zadań wymagających dużej mocy obliczeniowej.

Poniżej znajduje się diagram przedstawiający działanie Web Workera w JavaScript.

Główny wątek i Web Worker mogą komunikować się za pomocą przekazywania komunikatów. Używając Wyślij wiadomość sposób wysyłania wiadomości i wiadomość obsługi zdarzeń do odbierania wiadomości, możesz przekazywać instrukcje lub dane tam iz powrotem.

Tworzenie Web Workera

Aby utworzyć Web Worker, musisz utworzyć osobny plik JavaScript.

Oto przykład:

// main.js

// Utwórz nowego Web Workera
konst pracownik = nowy Pracownik(„pracownik.js”);

// Wyślij wiadomość do Web Workera
pracownik.postMessage(„Cześć z głównego wątku!”);

// Nasłuchuj wiadomości od Web Workera
pracownik.onmessage = funkcjonować(wydarzenie) {
konsola.dziennik(„Otrzymano wiadomość od Web Worker:”, zdarzenie.dane);
};

Powyższy przykład tworzy nowy proces roboczy sieci Web, przekazując ścieżkę do skryptu procesu roboczego (pracownik.js) jako argument do Pracownik konstruktor. Możesz wysłać wiadomość do Web Worker za pomocą Wyślij wiadomość metody i nasłuchuj komunikatów od Web Worker za pomocą wiadomość obsługa zdarzeń.

Następnie powinieneś utworzyć skrypt roboczy (pracownik.js) plik:

// pracownik.js

// Nasłuchuj wiadomości z głównego wątku
wiadomość.własna = funkcjonować(wydarzenie) {
konsola.dziennik(„Otrzymano wiadomość z głównego wątku:”, zdarzenie.dane);

// Wyślij wiadomość z powrotem do głównego wątku
self.postMessage(„Witaj z pliku worker.js!”);
};

Skrypt Web Worker nasłuchuje komunikatów z głównego wątku przy użyciu wiadomość obsługa zdarzeń. Po otrzymaniu wiadomości wylogowujesz wiadomość w środku zdarzenie.dane i wyślij nową wiadomość do głównego wątku z Wyślij wiadomość metoda.

Wykorzystanie równoległości z pracownikami sieci Web

Podstawowym przypadkiem użycia dla Web Workers jest równoległe wykonywanie zadań JavaScript o dużej mocy obliczeniowej. Przenosząc te zadania na Web Workerów, można osiągnąć znaczną poprawę wydajności.

Oto przykład użycia pracownika sieciowego do wykonania ciężkich obliczeń:

// main.js

konst pracownik = nowy Pracownik(„pracownik.js”);

// Wyślij dane do Web Workera do obliczeń
pracownik.postMessage([1, 2, 3, 4, 5]);

// Posłuchaj wyniku z Web Worker
pracownik.onmessage = funkcjonować(wydarzenie) {
konst wynik = zdarzenie.dane;
konsola.dziennik('Wynik obliczenia:', wynik);
};

Worker.js:

// Nasłuch danych z głównego wątku
wiadomość.własna = funkcjonować (wydarzenie) {
konst liczby = zdarzenie.dane;

konst wynik = wykonaj ciężkie obliczenie (liczby);

// Wyślij wynik z powrotem do głównego wątku
self.postMessage (wynik);
};

funkcjonowaćwykonać ciężkie obliczenia(dane) {
// Wykonaj złożone obliczenia na tablicy liczb
powrót dane
.mapa((numer) =>Matematyka.pow (liczba, 3)) // Sześcianuj każdą liczbę
.filtr((numer) => liczba % 20) // Filtruj liczby parzyste
.zmniejszyć((suma, liczba) => suma + liczba, 0); // Zsumuj wszystkie liczby
}

W tym przykładzie przekazujesz tablicę liczb z głównego wątku do Web Workera. Web Worker wykonuje obliczenia przy użyciu dostarczonej tablicy danych i wysyła wynik z powrotem do głównego wątku. The wykonaj ciężkie obliczenie() Funkcja odwzorowuje każdą liczbę na jej kostkę, odfiltrowuje liczby parzyste i ostatecznie je sumuje.

Ograniczenia i uwagi

Podczas gdy Web Workers zapewniają mechanizm osiągania równoległości w JavaScript, ważne jest, aby wziąć pod uwagę kilka ograniczeń i kwestii:

  • Brak pamięci współdzielonej: Web Workers działają w osobnych wątkach i nie współdzielą pamięci z głównym wątkiem. Nie mogą więc bezpośrednio uzyskiwać dostępu do zmiennych lub obiektów z głównego wątku bez przekazywania komunikatów.
  • Serializacja i deserializacja: Podczas przekazywania danych między głównym wątkiem a procesami roboczymi sieci Web należy serializować i deserializować dane, ponieważ przekazywanie komunikatów jest komunikacją tekstową. Ten proces wiąże się z kosztem wydajności i może mieć wpływ na ogólną wydajność aplikacji.
  • Obsługa przeglądarki: Chociaż procesy robocze sieci Web są dobrze obsługiwane w większości nowoczesnych przeglądarek internetowych, niektóre starsze przeglądarki lub ograniczone środowiska mogą mieć częściową obsługę procesów roboczych sieci Web lub nie być w ogóle obsługiwana.

Osiągnij prawdziwą równoległość w JavaScript

Równoległość w JavaScript to ekscytująca koncepcja, która umożliwia prawdziwie współbieżne wykonywanie zadań, nawet w języku z założenia jednowątkowym. Wraz z wprowadzeniem Web Workers możesz wykorzystać moc równoległości i osiągnąć znaczną poprawę wydajności aplikacji JavaScript.