Node.js Version 0.10 wurde heute veröffentlicht und eingeführt setImmediate
. In der API-Änderungsdokumentation wird vorgeschlagen , sie bei rekursiven nextTick
Aufrufen zu verwenden.
Nach dem, was MDN sagt , scheint es sehr ähnlich zu sein process.nextTick
.
Wann soll ich verwenden nextTick
und wann soll ich verwenden setImmediate
?
javascript
node.js
setimmediate
Benjamin Gruenbaum
quelle
quelle
nextTick
geht hervor, dass dies schneller ist alssetImmediate
bei großen Berechnungen.setImmediate
detaillierter, was funktioniert.setImmediate
, aber nicht vorhernextTick
?Antworten:
Verwenden
setImmediate
Sie diese Option, wenn Sie die Funktion hinter den E / A-Ereignisrückrufen in die Warteschlange stellen möchten, die sich bereits in der Ereigniswarteschlange befinden. Verwenden Sieprocess.nextTick
diese Option, um die Funktion am Anfang der Ereigniswarteschlange effektiv in die Warteschlange zu stellen, sodass sie unmittelbar nach Abschluss der aktuellen Funktion ausgeführt wird.In einem Fall, in dem Sie versuchen, einen lang laufenden, CPU-gebundenen Job mithilfe der Rekursion aufzubrechen, möchten Sie jetzt die nächste Iteration verwenden,
setImmediate
anstatt sieprocess.nextTick
in die Warteschlange zu stellen, da sonst Rückrufe von E / A-Ereignissen keine Chance hätten zwischen Iterationen laufen.quelle
requestAnimationFrame
da es nicht immer vorkommt (ich habe dies definitiv gesehen, ich denke, Beispiel war Tab war nicht aktueller Tab) und es kann aufgerufen werden, bevor die Seite fertig gemalt wurde (dh der Browser ist noch mit Zeichnen beschäftigt).Als Illustration
gibt die folgende Ausgabe
Ich hoffe, dies kann helfen, den Unterschied zu verstehen.
Aktualisiert:
quelle
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:
Diese Antwort beantwortet also nicht wirklich den genauen Unterschied, sondern lediglich ein Beispiel, das in verschiedenen Kontexten variieren kannIch denke, ich kann das ganz gut veranschaulichen. Da
nextTick
es am Ende der aktuellen Operation aufgerufen wird, kann ein rekursiver Aufruf dazu führen, dass die Ereignisschleife nicht mehr fortgesetzt wird.setImmediate
Löst dies, indem in der Prüfphase der Ereignisschleife ausgelöst wird, sodass die Ereignisschleife normal fortgesetzt werden kann.Quelle: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
Beachten Sie, dass die Überprüfungsphase unmittelbar nach der Abfragephase liegt. Dies liegt daran, dass die Abfragephase und E / A-Rückrufe die wahrscheinlichsten Orte
setImmediate
sind, an denen Ihre Anrufe ausgeführt werden. Im Idealfall sind die meisten dieser Aufrufe tatsächlich ziemlich unmittelbar, nur nicht so unmittelbar, wienextTick
dies nach jeder Operation überprüft wird und technisch außerhalb der Ereignisschleife vorhanden ist.Schauen wir uns ein kleines Beispiel für den Unterschied zwischen
setImmediate
und anprocess.nextTick
:Angenommen, wir haben gerade dieses Programm ausgeführt und durchlaufen die erste Iteration der Ereignisschleife. Es wird die
step
Funktion mit der Iteration Null aufgerufen . Anschließend werden zwei Handler registriert, einer fürsetImmediate
und einer fürprocess.nextTick
. Wir rufen diese Funktion dann rekursiv vomsetImmediate
Handler auf, der in der nächsten Prüfphase ausgeführt wird. DernextTick
Handler wird am Ende der aktuellen Operation ausgeführt und unterbricht die Ereignisschleife. Obwohl er als zweiter registriert wurde, wird er tatsächlich zuerst ausgeführt.Die Reihenfolge lautet:
nextTick
Wird ausgelöst, wenn die aktuelle Operation endet, die nächste Ereignisschleife beginnt, normale Ereignisschleifenphasen ausgeführt werden, wirdsetImmediate
ausgelöst und ruft rekursiv unserestep
Funktion auf, um den Prozess erneut zu starten. Der aktuelle Betrieb endet,nextTick
Brände usw.Die Ausgabe des obigen Codes wäre:
Verschieben wir nun unseren rekursiven Aufruf
step
in unserennextTick
Handler anstelle dessetImmediate
.Nachdem wir den rekursiven Aufruf
step
in dennextTick
Handler verschoben haben, verhalten sich die Dinge in einer anderen Reihenfolge. Unsere erste Iteration der Ereignisschleife wird ausgeführt und ruft diestep
Registrierung einessetImmedaite
Handlers sowie einesnextTick
Handlers auf. NachnextTick
Beendigung der aktuellen Operation wird unser Handler ausgelöst, der rekursiv einenstep
anderensetImmediate
Handler sowie einen anderennextTick
Handler aufruft und registriert . Da einnextTick
Handler nach der aktuellen Operation ausgelöst wird , führt das Registrieren einesnextTick
Handlers in einemnextTick
Handler dazu, dass der zweite Handler unmittelbar nach Abschluss der aktuellen Handleroperation ausgeführt wird. DienextTick
Handler feuern weiter und verhindern so, dass die aktuelle Ereignisschleife jemals fortgesetzt wird. Wir werden alle unsere durchstehennextTick
Handler, bevor wir ein einzelnessetImmediate
Handlerfeuer sehen.Die Ausgabe des obigen Codes lautet:
Beachten Sie, dass, wenn wir den rekursiven Aufruf nicht unterbrochen und nach 10 Iterationen abgebrochen
nextTick
hätten, die Aufrufe immer wieder rekursiv würden und die Ereignisschleife niemals zur nächsten Phase übergehen würde. Auf diese WeisenextTick
kann es bei rekursiver Verwendung blockiert werden, währendsetImmediate
das Auslösen in der nächsten Ereignisschleife und das Festlegen eines anderensetImmediate
Handlers innerhalb einer Schleife die aktuelle Ereignisschleife überhaupt nicht unterbricht, sodass die Phasen der Ereignisschleife wie gewohnt weiter ausgeführt werden können.Ich hoffe, das hilft!
PS - Ich stimme anderen Kommentatoren zu, dass die Namen der beiden Funktionen leicht ausgetauscht werden könnten, da es so
nextTick
klingt, als würde es in der nächsten Ereignisschleife und nicht am Ende der aktuellen ausgelöst, und das Ende der aktuellen Schleife ist "unmittelbarer" "als der Beginn der nächsten Schleife. Na ja, das bekommen wir, wenn eine API ausgereift ist und die Leute von vorhandenen Schnittstellen abhängig werden.quelle
In den Kommentaren in der Antwort wird nicht explizit angegeben, dass nextTick von Makrosemantik zu Mikrosemantik verschoben wurde.
Vor dem Knoten 0.9 (als setImmediate eingeführt wurde) wurde nextTick zu Beginn des nächsten Callstacks ausgeführt.
Seit Knoten 0.9 wird nextTick am Ende des vorhandenen Callstacks ausgeführt, während setImmediate am Anfang des nächsten Callstacks steht
Tools und Details finden Sie unter https://github.com/YuzuJS/setImmediate
quelle
In einfachen Worten, process.NextTick () würde beim nächsten Tick der Ereignisschleife ausgeführt. Das setImmediate verfügt jedoch grundsätzlich über eine separate Phase, die sicherstellt, dass der unter setImmediate () registrierte Rückruf erst nach der E / A-Rückruf- und Abfragephase aufgerufen wird.
Weitere Informationen finden Sie unter diesem Link: https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and -its -metrics-c4907b19da4c
quelle
Hier einige großartige Antworten, die detailliert beschreiben, wie beide funktionieren.
Fügen Sie einfach eine hinzu, die die gestellte Frage beantwortet:
Immer benutzen
setImmediate
.Die Node.js-Ereignisschleife, die Timer und das
process.nextTick()
Dokument enthalten Folgendes:Früher im Dokument warnt es, dass
process.nextTick
...Wie sich herausstellt,
process.nextTick
kann sogar verhungernPromises
:Auf der anderen Seite
setImmediate
ist es " einfacher zu überlegen " und vermeidet diese Art von Problemen:So sei denn , es gibt einen besonderen Bedarf für das einzigartige Verhalten
process.nextTick
, ist der empfohlene Ansatz zur „ VerwendungsetImmediate()
in allen Fällen “.quelle
Ich empfehle Ihnen, den Abschnitt zu Dokumenten zu lesen , der für Loop vorgesehen ist, um ein besseres Verständnis zu erhalten. Ein Ausschnitt von dort:
Wir haben zwei Anrufe, die für Benutzer ähnlich sind, deren Namen jedoch verwirrend sind.
process.nextTick () wird sofort in derselben Phase ausgelöst
setImmediate () wird bei der folgenden Iteration oder 'Tick' der
Ereignisschleife ausgelöst
Im Wesentlichen sollten die Namen ausgetauscht werden. process.nextTick () wird sofort ausgelöst als setImmediate (), aber dies ist ein Artefakt der Vergangenheit, das sich wahrscheinlich nicht ändern wird.
quelle