Jednowątkowa natura JavaScript/Typescript: programowanie asynchroniczne

Jan 20 2023
W moim pierwszym artykule napisałem o niektórych różnicach między JS a TS. Teraz zbadamy naturę asynchroniczną jako język z pojedynczym wątkiem.

W moim pierwszym artykule napisałem o niektórych różnicach między JS a TS.

Teraz zbadamy naturę asynchroniczną jako język z pojedynczym wątkiem.

W JavaScript i TypeScript charakter jednowątkowy oznacza, że ​​tylko jedno zadanie może być wykonane w danym momencie.

Z drugiej strony programowanie asynchroniczne odnosi się do zdolności języka do wykonywania zadań asynchronicznie, umożliwiając kontynuowanie głównego wątku wykonywania podczas oczekiwania na zakończenie innych zadań. Osiąga się to za pomocą wywołań zwrotnych , zdarzeń , obietnic i async / await .

Zanim zacznę wyjaśniać to w kategoriach kodowania, chciałbym omówić bardzo interesujące odniesienie do tego, jak zadania asynchroniczne w języku jednowątkowym są bardzo podobne do naszego mózgu, gdy próbujemy wykonywać wiele zadań .

W tej sekcji podsumuję długi tekst/rozdział napisany przez Kyle'a Simpsona w jego książce „You Dont Know Javascript” na temat połączenia Sequential Brain z asynchronizacją. Jeśli interesuje Cię tylko kodowanie, jak to działa, możesz pominąć tę część.

„ Jestem prawie pewien, że większość z was słyszała, jak ktoś powiedział (nawet sam to stwierdził): „ Jestem wielozadaniowcem. ”
Ale czy jesteśmy wielozadaniowi? Czy naprawdę możemy wykonać dwa świadome, celowe działania na raz i myśleć/rozumować o obu z nich dokładnie w tym samym momencie? Czy nasz najwyższy poziom funkcjonalności mózgu ma równoległą wielowątkowość?

Odpowiedź może Cię zaskoczyć, a brzmi: raczej nie.

Po prostu nie tak wyglądają nasze mózgi. Jesteśmy znacznie bardziej pojedynczymi zadaniami, niż wielu z nas chciałoby przyznać. Tak naprawdę w danej chwili możemy myśleć tylko o jednej rzeczy.

Nie mówię o wszystkich naszych mimowolnych, podświadomych, automatycznych funkcjach mózgu, takich jak bicie serca, oddychanie i mruganie powiekami. To wszystko są kluczowe zadania dla naszego zrównoważonego życia, ale celowo nie przeznaczamy na nie żadnej mocy mózgu”.

Według Simpsona, ludzie nie są zdolni do prawdziwie wielozadaniowej pracy w taki sam sposób, jak komputer. Chociaż prawdą jest, że ludzki mózg może przetwarzać wiele zadań jednocześnie, nie jest w stanie poświęcić równej uwagi wszystkim zadaniom jednocześnie. Zamiast tego szybko przełączamy naszą uwagę między zadaniami, podobnie jak pojedynczy program wielowątkowy może wykonywać tylko jedno zadanie na raz.

Na szczęście, podczas gdy mamy obsesję na punkcie sprawdzania kanałów społecznościowych po raz 15 w ciągu trzech minut, nasz mózg wykonuje wszystkie te ważne zadania w tle (wątki!).

Kiedy udajemy wielozadaniowość, na przykład próbujemy coś wpisać w tym samym czasie, gdy rozmawiamy przez telefon ze znajomym lub członkiem rodziny, najprawdopodobniej działamy jak szybkie przełączanie kontekstu . Innymi słowy, szybko przełączamy się między dwoma lub więcej zadaniami, jednocześnie wykonując każde zadanie w małych, szybkich fragmentach. Robimy to tak szybko, że światu zewnętrznemu wydaje się, że robimy te rzeczy równolegle.

Czy to brzmi jak asynchroniczna współbieżność zdarzeń (tak jak to, co dzieje się w JS) dla ciebie ?!

Istnieje duża, zauważalna różnica między tym, jak planujemy różne zadania, a tym, jak nasze mózgi realizują te zadania.
Chociaż na poziomie operacyjnym nasze mózgi są asynchroniczne, wydaje się, że planujemy zadania w sekwencyjny, synchroniczny sposób. „Muszę iść do sklepu, potem kupić trochę mleka, a potem oddać pranie chemiczne”.

Czy możesz sobie wyobrazić sposób myślenia, który planuje twoje sprawy do załatwienia w następujący sposób:

„ Muszę iść do sklepu (1), ale po drodze na pewno dostanę telefon (2) , więc „Cześć, mamo” i kiedy ona zacznie mówić, będę patrzeć w górę adres sklepu (3) na GPS, ale ładowanie zajmie sekundę, więc ściszę radio (4) , żeby lepiej słyszeć mamę…
wtedy zdaję sobie sprawę, że zapomniałem założyć kurtkę ( 5) i na zewnątrz jest zimno, ale nieważne, jedź dalej i rozmawiaj z mamą…
a potem dźwięk pasów przypomina mi o zapięciu pasów (6), więc „Tak, mamo, zawsze zapinam pasy!”. Ach, w końcu:

GPS dostał wskazówki, teraz…”

Bez względu na to, jak absurdalnie brzmi to jako sformułowanie tego, jak planujemy nasz dzień i myślimy o tym, co robić iw jakiej kolejności, to jednak dokładnie tak działają nasze mózgi na poziomie funkcjonalnym. Pamiętaj jednak, że to nie jest wielozadaniowość, to po prostu szybkie przełączanie kontekstu.

Mając to na uwadze, przyjrzyjmy się bliżej, jak działa programowanie asynchroniczne w JavaScript.

Teraz do kodowania :

Istnieje kilka sposobów wykonywania programowania asynchronicznego w JavaScript/Typescript, jak wspomniałem na początku tego artykułu, w tym za pomocą: Callbacks , Events, Promises, Async/Await.

  • Wywołanie zwrotne to funkcja przekazywana jako argument do innej funkcji i wykonywana po zakończeniu działania funkcji zewnętrznej. Na przykład:
  • function greet(name, callback) {
      console.log(`Hello, ${name}!`);
      callback();
    }
    
    function sayGoodbye() {
      console.log("Goodbye!");
    }
    
    greet("John", sayGoodbye);
    // Output: "Hello, John!"
    // Output: "Goodbye!"
    

  • Zdarzenie jest sygnałem, że coś się wydarzyło , a słuchacz to funkcja wykonywana w odpowiedzi na to zdarzenie. Na przykład:
  • const button = document.querySelector("button");
    
    button.addEventListener("click", () => {
      console.log("Button was clicked!");
    });
    

  • Obietnica reprezentuje wynik operacji asynchronicznej i może zostać rozwiązana (powodzenie) lub odrzucona (niepowodzenie), tak jak prawdziwe obietnice ; kiedy składasz obietnicę, albo ją dotrzymujesz (rozwiązujesz), albo nie (odrzucasz).
    Obietnice mogą służyć do uproszczenia procesu łączenia operacji asynchronicznych. Na przykład:
  • const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("Completed Async Task");
      }, 1000);
    });
    
    promise.then((result) => {
      console.log(result);
    });
    // Output: "Async task completed" (after 1 second)
    

  • Async/await: funkcja JavaScript, która umożliwia użycie składni async/await, aby kod asynchroniczny wyglądał i zachowywał się jak kod zsynchronizowany. Async/await opiera się na obietnicach i ułatwia pracę z kodem asynchronicznym.
  • async function greet(name) {
      return `Hello, ${name}!`;
    }
    
    async function main() {
      const greeting = await greet("John");
      console.log(greeting);
    }
    
    main();
    // Output: "Hello, John!"
    

Ogólnie rzecz biorąc, programowanie asynchroniczne pozwala na wykonywanie wielu zadań przy zachowaniu jednowątkowego charakteru języka. Pozwala na bardziej responsywny i wydajny program, umożliwiając kontynuowanie głównego wątku podczas oczekiwania na zakończenie innych zadań.

Jeśli podoba Ci się ten materiał, nie wahaj się go śledzić. Jest wiele innych projektów, o których planuję napisać w najbliższej przyszłości. Dopóki,

Dziękuję za przeczytanie!