Wersja 0.10 Node.js została wydana dzisiaj i wprowadzona setImmediate
. Dokumentacja zmian interfejsu API sugeruje używanie go podczas wykonywania nextTick
połączeń rekurencyjnych .
Z tego, co mówi MDN , wydaje się bardzo podobne process.nextTick
.
Kiedy powinienem nextTick
i kiedy powinienem setImmediate
?
javascript
node.js
setimmediate
Benjamin Gruenbaum
źródło
źródło
nextTick
jest szybszy niżsetImmediate
przy dużych obliczeniach.setImmediate
robi bardziej szczegółowo.setImmediate
, ale nie wcześniejnextTick
?Odpowiedzi:
Użyj,
setImmediate
jeśli chcesz ustawić w kolejce funkcję za wywołaniami zwrotnymi zdarzeń we / wy, które już znajdują się w kolejce zdarzeń. Służyprocess.nextTick
do skutecznego umieszczania w kolejce funkcji na początku kolejki zdarzeń, aby działała natychmiast po zakończeniu bieżącej funkcji.Tak więc w przypadku, gdy próbujesz przerwać długotrwałe, związane z procesorem zadanie za pomocą rekurencji, wolisz teraz użyć
setImmediate
zamiastprocess.nextTick
kolejkować kolejną iterację, ponieważ w przeciwnym razie wywołania zwrotne zdarzeń we / wy nie miałyby szansy biegać między iteracjami.źródło
requestAnimationFrame
ponieważ nie zawsze tak się dzieje (na pewno to widziałem, myślę, że przykład była tabulacją, a nie obecną tabulatorem) i można ją wywołać przed zakończeniem malowania strony (tzn. Przeglądarka jest nadal zajęta rysowaniem).Jako ilustracja
da następujący wynik
Mam nadzieję, że to pomoże zrozumieć różnicę.
Zaktualizowano:
źródło
For example, if we run the following script which is not within an I/O cycle (i.e. the main module), the order in which the two timers are executed is non-deterministic, as it is bound by the performance of the process:
Tak więc ta odpowiedź tak naprawdę nie odpowiada dokładnej różnicy, a jedynie przykład, który może się różnić w innym kontekścieMyślę, że mogę to całkiem dobrze zilustrować. Ponieważ
nextTick
jest wywoływany pod koniec bieżącej operacji, wywołanie go rekurencyjnie może w rezultacie zablokować kontynuowanie pętli zdarzeń.setImmediate
rozwiązuje to, uruchamiając w fazie sprawdzania pętli zdarzeń, umożliwiając normalne kontynuowanie pętli zdarzeń.źródło: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
Zauważ, że faza sprawdzania następuje bezpośrednio po fazie odpytywania. Wynika to z faktu, że faza odpytywania i wywołania zwrotne we / wy są najbardziej prawdopodobnymi miejscami, w
setImmediate
których będą uruchamiane połączenia. Idealnie więc większość z tych wywołań będzie faktycznie natychmiastowa, ale nie tak natychmiastowa, jaknextTick
jest sprawdzana po każdej operacji i technicznie istnieje poza pętlą zdarzeń.Rzućmy okiem na mały przykład różnicy między
setImmediate
iprocess.nextTick
:Powiedzmy, że właśnie uruchomiliśmy ten program i wykonujemy pierwszą iterację pętli zdarzeń. Wywoła
step
funkcję z iteracją zero. Następnie zarejestruje dwa moduły obsługi, jeden dlasetImmediate
i jeden dlaprocess.nextTick
. Następnie rekurencyjnie wywołujemy tę funkcję z modułusetImmediate
obsługi, który będzie działał w następnej fazie sprawdzania. ProceduranextTick
obsługi uruchomi się na końcu bieżącej operacji, przerywając pętlę zdarzeń, więc nawet jeśli została zarejestrowana jako druga, faktycznie uruchomi się jako pierwsza.Kolejność jest następująca:
nextTick
uruchamia się po zakończeniu bieżącej operacji, rozpoczyna się kolejna pętla zdarzeń, wykonywane są normalne fazy pętli zdarzeń,setImmediate
odpala i rekurencyjnie wywołuje nasząstep
funkcję, aby rozpocząć proces od nowa. Bieżąca operacja kończy się,nextTick
pożary itp.Dane wyjściowe powyższego kodu to:
Teraz przenieśmy nasze rekurencyjne wywołanie do
step
naszegonextTick
modułu obsługi zamiastsetImmediate
.Po przeniesieniu wywołania rekurencyjnego do
step
modułunextTick
obsługi wszystko będzie się zachowywać w innej kolejności. Nasza pierwsza iteracja pętli zdarzeń działa i wywołujestep
rejestrację modułusetImmedaite
obsługi i modułunextTick
obsługi. Po zakończeniu bieżącej operacji nasznextTick
moduł obsługi odpala, który rekurencyjnie wywołujestep
i rejestruje innysetImmediate
moduł obsługi, a także innynextTick
moduł obsługi. Ponieważ programnextTick
obsługi uruchamia się po bieżącej operacji, zarejestrowanie programunextTick
obsługi wnextTick
module obsługi spowoduje, że drugi moduł obsługi zostanie uruchomiony natychmiast po zakończeniu bieżącej operacji modułu obsługi. ProcedurynextTick
obsługi będą nadal odpalać, zapobiegając kontynuacji bieżącej pętli zdarzeń. Przejdziemy przez wszystkie naszenextTick
setImmediate
handlerów, zanim zobaczymy, że wystrzelił jednego handlera.Wynikiem powyższego kodu jest:
Zauważ, że gdybyśmy nie przerwali połączenia rekurencyjnego i nie przerwali go po 10 iteracjach,
nextTick
połączenia będą się powtarzać i nigdy nie pozwolą pętli zdarzeń przejść do następnej fazy. W ten sposóbnextTick
może zostać zablokowany, gdy zostanie użyty rekurencyjnie, podczas gdysetImmediate
będzie uruchamiany w następnej pętli zdarzeń, a ustawienie innego modułusetImmediate
obsługi z jednego z nich w ogóle nie zakłóci bieżącej pętli zdarzeń, umożliwiając normalne kontynuowanie wykonywania faz pętli zdarzeń.Mam nadzieję, że to pomaga!
PS - Zgadzam się z innymi komentatorami, że nazwy dwóch funkcji można łatwo zamienić, ponieważ
nextTick
brzmi to tak, jakby zadziałało w następnej pętli zdarzeń, a nie na końcu bieżącej, a koniec bieżącej pętli jest bardziej „natychmiastowy” ”niż początek następnej pętli. No cóż, to właśnie dostajemy, gdy API dojrzewa i ludzie zaczynają polegać na istniejących interfejsach.źródło
W komentarzach w odpowiedzi nie stwierdza się wyraźnie, że nextTick przeszedł z makrosemantyki na mikrosemantykę.
przed węzłem 0.9 (kiedy wprowadzono setImmediate), nextTick działał na początku następnego stosu wywołań.
od węzła 0.9 nextTick działa na końcu istniejącego stosu wywołań, podczas gdy setImmediate jest na początku następnego stosu wywołań
sprawdź https://github.com/YuzuJS/setImmediate po narzędzia i szczegóły
źródło
Mówiąc najprościej, process.NextTick () byłby wykonywany przy następnym tiku pętli zdarzeń. Jednak setImmediate ma zasadniczo osobną fazę, która zapewnia, że wywołanie zwrotne zarejestrowane w setImmediate () będzie wywoływane dopiero po fazie oddzwonienia i odpytywania We / Wy.
Proszę zapoznać się z tym linkiem, aby uzyskać ładne wyjaśnienie: https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and -its-metrics-c4907b19da4c
źródło
Oto kilka świetnych odpowiedzi opisujących ich działanie.
Wystarczy dodać taką, która odpowiada na konkretne zadane pytanie:
Zawsze używaj
setImmediate
.Node.js pętli zdarzeń, timery, a
process.nextTick()
doc zawiera następujące elementy:Wcześniej w dokumencie ostrzega, że
process.nextTick
może prowadzić do ...Jak się okazuje,
process.nextTick
może nawet głodowaćPromises
:Z drugiej strony
setImmediate
jest „ łatwiejszy do uzasadnienia ” i pozwala uniknąć tego rodzaju problemów:Tak więc, chyba że istnieje szczególna potrzeba wyjątkowego zachowania
process.nextTick
, zalecanym podejściem jest „ używaćsetImmediate()
we wszystkich przypadkach ”.źródło
Polecam sprawdzić sekcję dokumentacji poświęconą Loop, aby lepiej zrozumieć. Niektóre fragmenty pobrane stamtąd:
Mamy dwa połączenia, które są podobne pod względem użytkowników, ale ich nazwy są mylące.
process.nextTick () odpala natychmiast na tej samej fazie
setImmediate () odpala w następnej iteracji lub „tik” w
pętli zdarzeń
Zasadniczo nazwy powinny zostać zamienione. process.nextTick () odpala szybciej niż setImmediate (), ale jest to artefakt z przeszłości, którego zmiana jest mało prawdopodobna.
źródło