CodeGym /Kursy /Frontend SELF PL /Asynchroniczność

Asynchroniczność

Frontend SELF PL
Poziom 43 , Lekcja 0
Dostępny

1.1 Podstawowe pojęcia asynchroniczności

Asynchroniczność w JavaScript pozwala na wykonywanie zadań w tle, nie blokując głównego wątku wykonania. To jest szczególnie ważne dla zadań, które mogą zająć znaczący czas, takich jak zapytania sieciowe, czytanie plików i timery. Teraz przyjrzymy się głównym koncepcjom programowania asynchronicznego w JavaScript i podamy przykłady użycia.

Jednowątkowy charakter JavaScript

JavaScript jest językiem jednowątkowym: oznacza to, że wykonuje kod sekwencyjnie w jednym wątku. Jednakże operacje asynchroniczne pozwalają na wykonywanie zadań w tle, uwalniając główny wątek dla innych zadań.

Event Loop (Pętla zdarzeń)

Pętla zdarzeń (Event Loop) jest kluczowym mechanizmem, który pozwala JavaScript przetwarzać zadania asynchroniczne. Pętla zdarzeń zarządza kolejką wiadomości (Message Queue) i kolejką mikrozadań (Microtask Queue), zapewniając wykonywanie operacji asynchronicznych.

  1. Kolejka wiadomości: zawiera zadania, takie jak obsługa zdarzeń, zapytania sieciowe i timery. Zadania z tej kolejki są wykonywane sekwencyjnie.
  2. Kolejka mikrozadań: zawiera zadania o wyższym priorytecie w porównaniu do zadań w kolejce wiadomości. Przykłady obejmują zakończenie promes i wywołania funkcji zwrotnych (callbacks) w mikrozadaniach.

Pętla zdarzeń stale sprawdza obie kolejki i wykonuje zadania z nich, gdy główny wątek staje się wolny.

Operacje asynchroniczne

Operacje asynchroniczne pozwalają na wykonywanie zadań w tle. Główne przykłady operacji asynchronicznych obejmują:

  • Timery (setTimeout, setInterval)
  • Obsługa zdarzeń
  • Zapytania sieciowe (np. XMLHttpRequest, Fetch API)
  • Czytanie/zapis plików (w Node.js)

Przyjrzyjmy się kilku przykładom operacji asynchronicznych.

1.2 Timery

Timery pozwalają na wykonywanie zadań z opóźnieniem lub w regularnych odstępach czasu.

Przykład użycia setTimeout

W tym przykładzie setTimeout ustawia wykonanie funkcji po 2 sekundach. W wyniku tego najpierw wyświetlane są Start i End, a następnie po 2 sekundach wyświetlane jest Executed after 2 seconds.

JavaScript
    
      console.log('Start');

      setTimeout(() => {
        console.log('Executed after 2 seconds');
      }, 2000);

      console.log('End');
    
  

Przykład użycia setInterval

W tym przykładzie setInterval wykonuje funkcję co sekundę, zwiększając licznik i wyświetlając jego wartość. Gdy licznik osiągnie 5, interwał jest czyszczony za pomocą clearInterval:

JavaScript
    
      let counter = 0;

      const intervalID = setInterval(() => {
        counter++;
        console.log(`Counter: ${counter}`);
        if (counter >= 5) {
          clearInterval(intervalID);
        }
      }, 1000);
    
  

1.3 Obsługa zdarzeń

Obsługa zdarzeń pozwala na wykonywanie kodu w odpowiedzi na działania użytkownika lub inne zdarzenia.

Przykład użycia obsługi zdarzeń

W tym przykładzie obsługa zdarzenia click jest dodawana do przycisku. Gdy użytkownik naciska przycisk, wyświetlane jest wiadomość Button clicked!:

HTML
    
      <!DOCTYPE html>
      <html>
        <head>
          <title>Event Handler Example</title>
        </head>
        <body>
          <button id="myButton">Click me</button>

          <script>
            const button = document.getElementById('myButton');

            button.addEventListener('click', () => {
              console.log('Button clicked!');
            });
          </script>
        </body>
      </html>
    
  

1.4 Zapytania sieciowe

Zapytania sieciowe pozwalają na wykonywanie asynchronicznych zapytań HTTP do serwera.

Przykład użycia XMLHttpRequest

W tym przykładzie tworzony jest asynchroniczny request GET do API, a po zakończeniu zapytania odpowiedź jest wyświetlana w konsoli:

JavaScript
    
      const xhr = new XMLHttpRequest();
      xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);

      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
          const response = JSON.parse(xhr.responseText);
          console.log(response);
        }
      };

      xhr.send();
    
  

1.5 Event Loop w akcji

Aby lepiej zrozumieć, jak działa Event Loop, przyjrzyjmy się następującemu przykładowi:

JavaScript
    
      console.log('Start');

      setTimeout(() => {
        console.log('Timeout 1');
      }, 0);

      Promise.resolve().then(() => {
        console.log('Promise 1');
      });

      setTimeout(() => {
        console.log('Timeout 2');
      }, 0);

      Promise.resolve().then(() => {
        console.log('Promise 2');
      });

      console.log('End');
    
  

Oczekiwane wyjście będzie następujące:

  • Start
  • End
  • Promise 1
  • Promise 2
  • Timeout 1
  • Timeout 2

W tym przykładzie najpierw wykonywane są operacje synchroniczne (console.log('Start') i console.log('End')). Następnie wykonywane są mikrozadania (obsługa promes), i dopiero po tym wykonywane są zadania z kolejki wiadomości (setTimeout).

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION