Was ist der Unterschied zwischen diesen beiden und wann werde ich einen über den anderen verwenden?
javascript
node.js
Shlomi Schwartz
quelle
quelle
Antworten:
setTimeout ist einfach wie das Aufrufen der Funktion nach Beendigung der Verzögerung. Wenn eine Funktion aufgerufen wird, wird sie nicht sofort ausgeführt, sondern in die Warteschlange gestellt, sodass sie ausgeführt wird, nachdem alle ausführenden und aktuell in die Warteschlange gestellten Eventhandler zuerst beendet wurden. setTimeout (, 0) bedeutet im Wesentlichen die Ausführung, nachdem alle aktuellen Funktionen in der aktuellen Warteschlange ausgeführt wurden. Es kann nicht garantiert werden, wie lange es dauern könnte.
setImmediate ist in dieser Hinsicht ähnlich, außer dass es keine Funktionswarteschlange verwendet. Es überprüft die Warteschlange der E / A-Ereignishandler. Wenn alle E / A-Ereignisse im aktuellen Snapshot verarbeitet werden, wird der Rückruf ausgeführt. Sie werden unmittelbar nach dem letzten E / A-Handler in die Warteschlange gestellt, ähnlich wie process.nextTick. Es geht also schneller.
Außerdem (setTimeout, 0) ist langsam, da der Timer vor der Ausführung mindestens einmal überprüft wird. Manchmal kann es doppelt so langsam sein. Hier ist ein Benchmark.
Ausgabe
Zunächst gibt man eine Vorstellung von schnellstmöglichen Anrufen. Sie können selbst überprüfen, ob setTimeout halb so oft aufgerufen wird wie andere. Denken Sie auch daran, dass setImmediate sich an Ihre Dateisystemaufrufe anpasst. Unter Last ist die Leistung also geringer. Ich denke nicht, dass setTimeout es besser machen kann.
setTimeout ist eine unaufdringliche Methode, um Funktionen nach einiger Zeit aufzurufen. Es ist genau wie im Browser. Es ist möglicherweise nicht für die Serverseite geeignet (denken Sie daran, warum ich Benchmark.js verwendet habe, nicht setTimeout).
quelle
Ein großartiger Artikel über die Funktionsweise der Ereignisschleife und die Beseitigung einiger Missverständnisse. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
Zitieren des Artikels:
setImmediate
Rückrufe werden aufgerufen, nachdem Rückrufe in der E / A-Warteschlange beendet wurden oder eine Zeitüberschreitung aufgetreten ist. setImmediate-Rückrufe werden in die Check Queue gestellt, die nach der E / A-Warteschlange verarbeitet werden.setTimeout(fn, 0)
Rückrufe werden in die Timer-Warteschlange gestellt und nach E / A-Rückrufen sowie Rückrufen in der Warteschlange überprüft. Verarbeiten Sie als Ereignisschleife die Timer-Warteschlange zuerst in jeder Iteration. Welche zuerst ausgeführt wird, hängt davon ab, um welche Phasenereignisschleife es sich handelt.quelle
Mit setImmediate () wird die sofortige Ausführung des Rückrufs nach Rückrufen von E / A-Ereignissen sowie vor setTimeout und setInterval geplant.
Mit setTimeout () wird die Ausführung eines einmaligen Rückrufs nach einer Verzögerung von Millisekunden geplant.
Das sagen die Dokumente.
Wenn Sie den obigen Code ausführen, sieht das Ergebnis folgendermaßen aus ... obwohl im aktuellen Dokument angegeben ist, dass "die" sofortige "Ausführung des Rückrufs nach Rückrufen von E / A-Ereignissen und vor setTimeout und setInterval geplant werden soll". ..
Ergebnis..
Wenn Sie Ihr Beispiel in einen anderen Timer einbinden, wird immer setImmediate gefolgt von setTimeout gedruckt.
quelle
Verwenden
setImmediate
Sie immer , es sei denn, Sie sind sich wirklich sicher, dass Sie brauchensetTimeout(,0)
(aber ich kann mir nicht einmal vorstellen, wofür).setImmediate
Rückruf wird fast immer vorher ausgeführtsetTimeout(,0)
, außer wenn er im ersten Tick und imsetImmediate
Rückruf aufgerufen wird .quelle
setTimeout
sollte die Anlaufstelle sein, mitsetImmediate
nur verwendet, wenn gezeigt wird, dass es notwendig ist.Völlig unzufrieden mit den gelieferten Antworten. Ich habe hier eine meiner Meinung nach bessere Antwort veröffentlicht: https://stackoverflow.com/a/56724489/5992714
Fragen ist ein mögliches Duplikat von Warum ist das Verhalten von setTimeout (0) und setImmediate () bei Verwendung im Hauptmodul undefiniert?
quelle
Ich denke, die Antwort von Navya S ist nicht richtig, hier ist mein Testcode:
Die Erklärungen finden Sie hier
quelle
setTimeout (fn, 0) kann verwendet werden, um zu verhindern, dass der Browser bei massiven Updates einfriert. In websocket.onmessage können sich beispielsweise HTML-Änderungen ergeben. Wenn weiterhin Nachrichten eingehen, friert der Browser möglicherweise ein, wenn setImmidiate verwendet wird
quelle
Um sie genau zu verstehen, gehen Sie bitte einmal die Phasen der Ereignisschleife durch.
SetImmediate: Wird in der "Check" -Phase ausgeführt. Die Kontrollphase wird nach der I / O - Phase genannt.
SetTimeOut: Wird in der "Timer" -Phase ausgeführt. Die Timer - Phase ist die erste Phase , aber nach der genannten E / A - Phase sowie die Preisphase.
Um die Ausgabe deterministisch zu erhalten, hängt es davon ab, in welcher Phase sich die Ereignisschleife befindet. Dementsprechend können wir die Funktion aus zwei verwenden.
quelle
Verwenden Sie setImmediate (), um die Ereignisschleife nicht zu blockieren. Der Rückruf wird in der nächsten Ereignisschleife ausgeführt, sobald die aktuelle abgeschlossen ist.
Verwenden Sie setTimeout () für kontrollierte Verzögerungen. Die Funktion wird nach der angegebenen Verzögerung ausgeführt. Die minimale Verzögerung beträgt 1 Millisekunde.
quelle