Podstawy działania Node'a

0

Cześć, usiadłem ostatnio trochę więcej do NodeJS ale chciałbym najpierw ogarnąć trochę podstaw działania samej V8 od Chrome'a na której Node stoi. No i tak sobie szukam i szukam czegoś po necie na temat zasad działania pętli zdarzeń, tego dlaczego Node jest jednowątkowy, czym są callbacki, event emmitery, itd. I w sumie sam nie wiem czy dobrze sobie na te pytania sobie odpowiadam, dlatego wypisze tutaj pytania i odpowiedzi i prosiłbym o weryfikacje i ewentualne poprawienie mnie w swoim myśleniu

  1. Dlaczego Node jest jednowątkowy?
    Generalnie przez wzgląd na to, że praca na jednym wątku jest dużo bardziej wydajna niż praca na kilku. Wykonując przetwarzanie asynchroniczne(asynchroniczność na jednym wątku...) w pojedynczym wątku przy typowych obciążeniach sieci Web, można osiągnąć większą wydajność

  2. Czym jest pętla zdarzeń?
    Każde nasze żądanie do serwera jest naszym I/O(czyli takim zdarzeniem typu input/ouptput tj. naciśnięcie klawisza i wywołanie operacji) czyli eventem, ten nasz event jest obsługiwany przez EventEmmiter który kolejno jest wrzucany do kolejki zdarzeń skąd ląduję w naszej pętli zdarzeń. W pętli zdarzeń jest sprawdzane między innymi to czy nasza operacja jest nie blokująca(nie blokująca czyli taka, która nie blokuje wywoływania innych operacji), jeśli dana operacja jest nieblokujące to ta operacja zostaje przetwarzana a później dodana do pętli zdarzeń która odsyła tę odpowiedź do klienta. Natomiast jeśli operacja jest blokująca, to z puli wewnętrznych wątków zostaje do naszej operacji przydzielony pojedynczy wątek odpowiedzialny za wykonanie określonego żądania, gdzie po wykonaniu operacji wątek jest zwalniany, a później operacja wraca do pętli zdarzeń by odesłać odpowiedź do klienta.

  3. Czym jest callback?
    Callback jest niczym innym jak funkcją wywoływaną po jakiejś operacji mającej na celu uniknąć blokowania operacji, Node w dużym stopniu polega na wywołaniach zwrotnych ponieważ ... (właśnie, dlaczego?)...

Szukam teraz eksperta od NodeJS który pokaże mi, że się mylę we wszystkim i uprzejmie naprowadzi mnie na poprawne myślenie w kwestii niskopoziomowych operacji w NodeJS :)

Dzięki za każdą odpowiedz!

4

Dlaczego Node jest jednowątkowy?
Generalnie przez wzgląd na to, że praca na jednym wątku jest dużo bardziej wydajna niż praca na kilku. Wykonując przetwarzanie asynchroniczne(asynchroniczność na jednym wątku...) w pojedynczym wątku przy typowych obciążeniach sieci Web, można osiągnąć większą wydajność

Bo V8 (na którym oparte jest Node) jest jednowątkowy? A V8 jest jednowątkowy, bo JS jest jednowątkowy? Do pełnej wielowątkowości potrzeba modelu pamięci, który obsługuje wielowątkowość, czyli synchronized, volatile, atomic, itp itd Ewentualnie można mieć ułomną wielowątkowość a'la taką jak w Pythonie, gdzie jest GIL (global interpreter lock) i de facto wykonywanie jest jednowątkowe, ale model programowania jest trochę zbliżony do prawdziwej wielowątkowości. Jeszcze inną możliwością jest pójście np. w mechanizm odizolowanych aktorów, ale to już całkowicie inny model programowania niż typowy JS.

Kolejną sprawą jest to, że w Pythonie, V8 i innych jednowątkowych środowiskach są często dodatkowe wątki na obsługę I/O (pliki, sieć, komunikacja międzyprocesowa, itd). Nie programujesz ich bezpośrednio, ale chodzą równolegle i dzięki temu przyspieszają I/O.

Szukam teraz eksperta od NodeJS który pokaże mi, że się mylę we wszystkim i uprzejmie naprowadzi mnie na poprawne myślenie w kwestii niskopoziomowych operacji w NodeJS :)

Ekspertem od Node nie jestem, więc to powyższe co napisałem jest tylko pewnym zarysem sytuacji. Czekamy na prawdziwego eksperta ;)

5

Node nie jest jednowątkowy, a przynajmniej nie do końca.

Sam Javascript jest jednowątkowy, ale sporo rzeczy które Node robi (operacje na plikach, zapytania sieciowe) to są funkcje napisane w C++. I Node to wykorzystuje i kiedy trzeba przetwarza je wielowątkowo.

Więc na pytanie - czy javascript jest jednowątkowy? Można odpowiedzieć - tak, jest.
Natomiast w przypadku Node, odpowiedź brzmi - to zależy.

Callback jest niczym innym jak funkcją wywoływaną po jakiejś operacji mającej na celu uniknąć blokowania operacji, Node w dużym stopniu polega na wywołaniach zwrotnych ponieważ ... (właśnie, dlaczego?)...

Callback jest po prostu sposobem na poinformowanie, że jakaś operacja została zakończona i można zrobić coś nowego z wynikiem tej operacji.
Raczej nie ma tu wielkiej filozofii, powstanie czegoś takiego było nieuniknione ze względu na asynchroniczny sposób działania javascriptu. W jakiś sposób trzeba było znać, kiedy jakiś proces się zakończył.

Callbacki były szeroko używane zanim do javascriptu weszły promisy i async/await.

Ale w momencie, kiedy node powstawało, promisy nie były tak szeroko rozpowszechnione, więc naturalnym było użycie callbacków.
Co ciekawe, twórca Node - Ryan Dahl żałuje, że postawił na callbacki, a nie promise (10 Things I Regret About Node.js - Ryan Dahl - JSConf EU po 5 minucie).

No ale wyszło jak wyszło.

Obecnie, jest raczej trend na przepisywania wszystkiego na promise. Większość API node już je wspiera. Są po prostu czytelniejsze.

2

Na dodatek promisy mają swoją własną kolejkę zdarzeń (microtask queue).
To ma taką śmieszną właściwość, że można zrobić wieczną pętlę za pomocą promisów (niby asynchroniczne, ale jednak blokujące, bo jeśli promise odpali drugiego promisa, to się uruchomi bezpośrednio po tym itp.).
więc to jest wieczną pętlą i zablokuje wykonywanie skryptu:

function foo() {  Promise.resolve().then(foo); }

a to już nie, bo setTimeout jest obsłużony osobno, jako macrotask:

function bar() {  setTimeout(bar, 0); }

tu jest więcej o tym (chociaż od strony przeglądarki). https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide

1

KLIKNIJ!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.