window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster już istnieje') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Asynchroniczny i jednowątkowy JavaScript? - The Codest
The Codest
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Branże
    • Fintech i bankowość
    • E-commerce
    • Adtech
    • Healthtech
    • Produkcja
    • Logistyka
    • Motoryzacja
    • IOT
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
Strzałka w tył WSTECZ
2020-03-31
Software Development

Asynchroniczny i jednowątkowy JavaScript?

Łukasz Kolko

JavaScript jest językiem jednowątkowym, a jednocześnie nieblokującym, asynchronicznym i współbieżnym. Ten artykuł wyjaśni ci, jak to się dzieje.

  • Czas działania

JavaScript jest językiem interpretowanym, a nie kompilowanym. Oznacza to, że potrzebuje on interpretera, który konwertuje JS kod do kodu maszynowego. Istnieje kilka rodzajów interpreterów (zwanych silnikami). Najpopularniejsze silniki przeglądarek to V8 (Chrome), Quantum (Firefox) i WebKit (Safari). Nawiasem mówiąc, V8 jest również używany w popularnym środowisku uruchomieniowym innym niż przeglądarka, Node.js.

Każdy silnik zawiera stertę pamięci, stos wywołań, pętlę zdarzeń, kolejkę wywołań zwrotnych i interfejs WebAPI z żądaniami HTTP, licznikami czasu, zdarzeniami itp., wszystkie zaimplementowane na swój własny sposób w celu szybszej i bezpieczniejszej interpretacji kodu JS.

Rozwój JavaScript

Podstawowa architektura środowiska uruchomieniowego JS. Autor: Alex Zlatkov

Pojedynczy wątek

Język jednowątkowy to język z pojedynczym stosem wywołań i pojedynczą stertą pamięci. Oznacza to, że w danym momencie wykonywana jest tylko jedna operacja.

A stos jest ciągłym regionem pamięci, alokującym lokalny kontekst dla każdej wykonywanej funkcji.

A sterta to znacznie większy region, przechowujący wszystko, co zostało przydzielone dynamicznie.

A stos wywołań to struktura danych, która zasadniczo rejestruje, gdzie jesteśmy w programie.

Stos wywołań

Napiszmy prosty kod i prześledźmy, co dzieje się na stosie wywołań.

Rozwój oprogramowania JavaScript

Jak widać, funkcje są dodawane do stosu, wykonywane, a następnie usuwane. Jest to tak zwany sposób LIFO - Last In, First Out. Każdy wpis na stosie wywołań jest nazywany ramka stosu.

Znajomość stosu wywołań jest przydatna do odczytywania śladów stosu błędów. Ogólnie rzecz biorąc, dokładna przyczyna błędu znajduje się na górze w pierwszej linii, chociaż kolejność wykonywania kodu jest oddolna.

Czasami można poradzić sobie z popularnym błędem, zgłaszanym przez Przekroczono maksymalny rozmiar stosu wywołań. Można to łatwo uzyskać za pomocą rekurencji:

function foo() {
    foo()
}
foo()

i nasza przeglądarka lub terminal zawiesza się. Każda przeglądarka, nawet w różnych wersjach, ma inny limit wielkości stosu wywołań. W zdecydowanej większości przypadków są one wystarczające i problemu należy szukać gdzie indziej.

Zablokowany stos wywołań

Oto przykład blokowania wątku JS. Spróbujmy odczytać plik foo i plik pasek przy użyciu WęzełFunkcja synchroniczna .js readFileSync.

Kod JavaScript

To jest zapętlony GIF. Jak widać, silnik JS czeka do pierwszego wywołania w pliku readFileSync jest zakończona. Ale tak się nie stanie, ponieważ nie ma foo więc druga funkcja nigdy nie zostanie wywołana.

Zachowanie asynchroniczne

Jednak JS może być również nieblokujący i zachowywać się tak, jakby był wielowątkowy. Oznacza to, że nie czeka na odpowiedź wywołania API, zdarzenia I/O itp. i może kontynuować wykonywanie kodu. Jest to możliwe dzięki silnikom JS, które wykorzystują (pod maską) prawdziwe języki wielowątkowe, takie jak C++ (Chrome) lub Rust (Firefox). Zapewniają nam one Web API pod maską przeglądarki lub np. I/O API pod Node.js.

Język programowania JavaScript

Na powyższym GIF-ie widzimy, że pierwsza funkcja jest wypychana na stos wywołań i Cześć jest natychmiast wykonywana w konsoli.

Następnie wywołujemy setTimeout dostarczana przez WebAPI przeglądarki. Przechodzi ona do stosu wywołań i jej asynchronicznego wywołania zwrotnego foo funkcja przechodzi do kolejki WebApi, gdzie czeka na połączenie, które ma nastąpić po 3 sekundach.

W międzyczasie program kontynuuje kod i widzimy Cześć, nie jestem zablokowany w konsoli.

Po wywołaniu, każda funkcja w kolejce WebAPI trafia do pliku Kolejka wywołania zwrotnego. Jest to miejsce, w którym funkcje czekają, aż stos wywołań będzie pusty. Gdy tak się stanie, są tam przenoszone jedna po drugiej.

Tak więc, kiedy nasz setTimeout timer zakończy odliczanie, nasz foo funkcja przechodzi do kolejki wywołania zwrotnego, czeka, aż stos wywołań stanie się dostępny, przechodzi tam, jest wykonywana i widzimy Cześć z asynchronicznego wywołania zwrotnego w konsoli.

Pętla zdarzeń

Pytanie brzmi, skąd środowisko wykonawcze wie, że stos wywołań jest pusty i jak wywoływane jest zdarzenie w kolejce wywołań zwrotnych? Poznaj pętlę zdarzeń. Jest ona częścią silnika JS. Proces ten stale sprawdza, czy stos wywołań jest pusty, a jeśli tak, monitoruje, czy w kolejce wywołań zwrotnych znajduje się zdarzenie oczekujące na wywołanie.

To cała magia za kulisami!

Podsumowując teorię

Współbieżność i równoległość

Współbieżność oznacza wykonywanie wielu zadań w tym samym czasie, ale nie jednocześnie. Np. dwa zadania działają w nakładających się okresach czasu.

Równoległość oznacza wykonywanie dwóch lub więcej zadań jednocześnie, np. wykonywanie wielu obliczeń w tym samym czasie.

Wątki i procesy

Nici są sekwencją wykonywania kodu, które mogą być wykonywane niezależnie od siebie.

Proces jest instancją uruchomionego programu. Program może mieć wiele procesów.

Synchroniczne i asynchroniczne

W synchroniczny W programowaniu zadania są wykonywane jedno po drugim. Każde zadanie czeka na zakończenie poprzedniego i dopiero wtedy jest wykonywane.

W asynchroniczny programowanie, gdy jedno zadanie jest wykonywane, można przełączyć się na inne zadanie bez czekania na zakończenie poprzedniego.

Synchroniczne i asynchroniczne w środowisku jedno- i wielowątkowym

Synchroniczne z pojedynczym wątkiem: Zadania są wykonywane jedno po drugim. Każde zadanie czeka na wykonanie poprzedniego zadania.

Synchroniczny z wieloma wątkami: Zadania są wykonywane w różnych wątkach, ale czekają na inne zadania wykonywane w innym wątku.

Asynchroniczny z pojedynczym wątkiem: Zadania zaczynają być wykonywane bez oczekiwania na zakończenie innego zadania. W danym momencie może być wykonywane tylko jedno zadanie.

Asynchroniczny z wieloma wątkami: Zadania są wykonywane w różnych wątkach bez oczekiwania na zakończenie innych zadań i kończą swoje wykonywanie niezależnie.

Klasyfikacja JavaScript

Jeśli weźmiemy pod uwagę, jak silniki JS działają pod maską, możemy sklasyfikować JS jako asynchroniczny i jednowątkowy język interpretowany. Słowo "interpretowany" jest bardzo ważne, ponieważ oznacza, że język zawsze będzie zależny od czasu wykonywania i nigdy nie będzie tak szybki jak języki kompilowane z wbudowaną wielowątkowością.

Warto zauważyć, że Node.js może osiągnąć prawdziwą wielowątkowość, pod warunkiem, że każdy wątek jest uruchamiany jako oddzielny proces. Istnieją do tego biblioteki, ale Node.js ma wbudowaną funkcję o nazwie Wątki pracownicze.

Wszystkie GIF-y pętli zdarzeń pochodzą z Lupa stworzona przez Philipa Robertsa, w której można testować asynchroniczne scenariusze.

Czytaj więcej:

Dlaczego (prawdopodobnie) powinieneś używać Typescript?

Jakość przede wszystkim! 5 prostych kroków do lintowania kodu za pomocą przepływów pracy GitHub w projekcie JavaScript

Jak ulepszyć aplikacje Vue.js? Kilka praktycznych wskazówek

Powiązane artykuły

Software Development

Tworzenie przyszłościowych aplikacji internetowych: spostrzeżenia zespołu ekspertów The Codest

Odkryj, w jaki sposób The Codest wyróżnia się w tworzeniu skalowalnych, interaktywnych aplikacji internetowych przy użyciu najnowocześniejszych technologii, zapewniając płynne doświadczenia użytkowników na wszystkich platformach. Dowiedz się, w jaki sposób nasza wiedza napędza transformację cyfrową i biznes...

THEECODEST
Software Development

10 najlepszych firm tworzących oprogramowanie na Łotwie

Dowiedz się więcej o najlepszych łotewskich firmach programistycznych i ich innowacyjnych rozwiązaniach w naszym najnowszym artykule. Odkryj, w jaki sposób ci liderzy technologiczni mogą pomóc w rozwoju Twojej firmy.

thecodest
Rozwiązania dla przedsiębiorstw i scaleupów

Podstawy tworzenia oprogramowania Java: Przewodnik po skutecznym outsourcingu

Zapoznaj się z tym niezbędnym przewodnikiem na temat skutecznego tworzenia oprogramowania Java outsourcing, aby zwiększyć wydajność, uzyskać dostęp do wiedzy specjalistycznej i osiągnąć sukces projektu z The Codest.

thecodest
Software Development

Kompletny przewodnik po outsourcingu w Polsce

Wzrost liczby outsourcing w Polsce jest napędzany przez postęp gospodarczy, edukacyjny i technologiczny, sprzyjający rozwojowi IT i przyjazny klimat dla biznesu.

TheCodest
Rozwiązania dla przedsiębiorstw i scaleupów

Kompletny przewodnik po narzędziach i technikach audytu IT

Audyty IT zapewniają bezpieczne, wydajne i zgodne z przepisami systemy. Dowiedz się więcej o ich znaczeniu, czytając cały artykuł.

The Codest
Jakub Jakubowicz CTO & Współzałożyciel

Subskrybuj naszą bazę wiedzy i bądź na bieżąco!

    O nas

    The Codest - Międzynarodowa firma programistyczna z centrami technologicznymi w Polsce.

    Wielka Brytania - siedziba główna

    • Office 303B, 182-184 High Street North E6 2JA
      Londyn, Anglia

    Polska - lokalne centra technologiczne

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polska

      The Codest

    • Strona główna
    • O nas
    • Nasze Usługi
    • Case Studies
    • Nasze Know How
    • Kariera
    • Słownik

      Nasze Usługi

    • Konsultacje IT
    • Software Development
    • Backend Development
    • Frontend Development
    • Zespoły IT
    • Backend Dev
    • Inżynierowie rozwiązań chmurowych
    • Inżynierowie danych
    • Inne
    • Inżynierowie QA

      Raporty

    • Fakty i mity na temat współpracy z zewnętrznym partnerem programistycznym
    • Z USA do Europy: Dlaczego amerykańskie startupy decydują się na relokację do Europy?
    • Porównanie centrów rozwoju Tech Offshore: Tech Offshore Europa (Polska), ASEAN (Filipiny), Eurazja (Turcja)
    • Jakie są największe wyzwania CTO i CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Warunki korzystania z witryny

    Copyright © 2025 by The Codest. Wszelkie prawa zastrzeżone.

    pl_PLPolish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek pl_PLPolish