Zagłębiłem się bardziej w wewnętrzne elementy architektury Node.js, a termin, który często pojawia się, to „tick”, jak w przypadku „next tick of the event loop” lub funkcja nextTick () .
To, czego nie widziałem, to solidna definicja tego, czym dokładnie jest „tik”. Opierając się na różnych artykułach ( takich jak ten ), udało mi się ułożyć koncepcję w mojej głowie, ale nie jestem pewien, czy jest dokładna.
Czy mogę uzyskać dokładny i szczegółowy opis taktu pętli zdarzeń Node.js?
Odpowiedzi:
Pamiętaj, że chociaż JavaScript jest jednowątkowy, wszystkie operacje we / wy węzła i wywołania natywnych interfejsów API są albo asynchroniczne (przy użyciu mechanizmów specyficznych dla platformy), albo działają w oddzielnym wątku. (To wszystko jest obsługiwane przez libuv.)
Tak więc, gdy w gnieździe są dostępne dane lub zwrócono natywną funkcję API, potrzebujemy zsynchronizowanego sposobu wywołania funkcji JavaScript zainteresowanej konkretnym zdarzeniem, które właśnie się wydarzyło.
Nie jest bezpieczne po prostu wywołanie funkcji JS z wątku, w którym zdarzenie natywne miało miejsce z tych samych powodów, które można spotkać w zwykłej aplikacji wielowątkowej - warunki wyścigu, nieatomowy dostęp do pamięci i tak dalej.
Więc to, co robimy, to umieszczanie zdarzenia w kolejce w sposób bezpieczny dla wątków. W nadmiernie uproszczonym psuedokodzie coś takiego:
Następnie wracając do głównego wątku JavaScript (ale po stronie C), robimy coś takiego:
while (true) { // this is the beginning of a tick lock (queue) { var tickEvents = copy(queue); // copy the current queue items into thread-local memory queue.empty(); // ..and empty out the shared queue } for (var i = 0; i < tickEvents.length; i++) { InvokeJSFunction(tickEvents[i]); } // this the end of the tick }
Element
while (true)
(który w rzeczywistości nie istnieje w kodzie źródłowym węzła; jest to czysto ilustracyjne) reprezentuje pętlę zdarzeń . Wewnętrznafor
wywołuje funkcję JS dla każdego zdarzenia, które było w kolejce.To jest tik: synchroniczne wywołanie zera lub większej liczby funkcji zwrotnych skojarzonych ze zdarzeniami zewnętrznymi. Gdy kolejka zostanie opróżniona i ostatnia funkcja powróci, tik się skończył. Wracamy do początku (następny tik) i sprawdzamy, czy zdarzenia, które zostały dodane do kolejki z innych wątków podczas działania naszego JavaScript .
Co może dodawać rzeczy do kolejki?
process.nextTick
setTimeout
/setInterval
fs
,net
i tak dalej)crypto
funkcje intensywnie wykorzystujące procesor, takie jak strumienie kryptograficzne, pbkdf2 i PRNG (które są w rzeczywistości przykładem ...)źródło
setImmediate
również kolejkuje funkcję.Prostsza odpowiedź dla nowicjuszy w JavaScript:
Pierwszą rzeczą do zrozumienia jest to, że JavaScript jest „środowiskiem jednowątkowym”. Odnosi się to do zachowania JavaScript polegającego na wykonywaniu bloków kodu pojedynczo z „pętli zdarzeń” w pojedynczym wątku. Poniżej znajduje się podstawowa implementacja pętli zdarzeń zaczerpnięta z książki Kyle'a Simpsona ydkJS, a następnie wyjaśnienie:
// `eventLoop` is an array that acts as a queue (first-in, first-out) var eventLoop = [ ]; var event; // keep going "forever" while (true) { // perform a "tick" if (eventLoop.length > 0) { // get the next event in the queue event = eventLoop.shift(); // now, execute the next event try { event(); } catch (err) { reportError(err); } } }
Pierwsza pętla while symuluje pętlę zdarzeń. Tik to dekolejkowanie zdarzenia z „kolejki pętli zdarzeń” i wykonanie tego zdarzenia.
Zobacz odpowiedź „Josh3796”, aby uzyskać bardziej szczegółowe wyjaśnienie tego, co dzieje się podczas dekolejowania i wykonywania zdarzenia.
Polecam również przeczytanie książki Kyle'a Simpsona tym, którzy chcą dogłębnie zrozumieć JavaScript. Jest całkowicie darmowy i typu open source i można go znaleźć pod tym linkiem: https://github.com/getify/You-Dont-Know-JS
Konkretną sekcję, do której się odwołałem, można znaleźć tutaj: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/sync-async/ch1.md
źródło
Bardzo prosta i krótka metoda zaznaczania pętli zdarzeń to:
Jest używany przez wewnętrzny mechanizm węzła, w którym po przetworzeniu zestawu żądań w kolejce inicjowany jest tick, który reprezentuje zakończenie zadania
źródło