ÜberblickWerfen wir zunächst einen kurzen Blick auf den Betriebsmechanismus der setTimeout-Verzögerung. setTimeout stellt die Rückruffunktion zuerst in die Warteschlange, und nachdem andere Hauptprogramme im Wartebereich ausgeführt wurden, wird die Rückruffunktion in chronologischer Reihenfolge ausgeführt. Es ist im Wesentlichen eine Frage des Umfangs. Wenn dies getan wird, wird daher nicht die gewünschte Ausgabe 1.2.3.4.5 erhalten, sondern es werden 5 aufeinanderfolgende 6er ausgegeben. für (var i=1; i<=5; i++) { setTimeout( Funktion Timer() { konsole.log( i ); }, i*1000 ); } Dies liegt daran, dass setTimeout asynchron ausgeführt wird. Bei jeder Ausführung der For-Schleife wird setTimeout einmal ausgeführt, die darin enthaltene Funktion wird jedoch nicht ausgeführt. Stattdessen wird sie in die Aufgabenwarteschlange gestellt und wartet auf die Ausführung. Erst wenn die Aufgaben in der Hauptzeile abgeschlossen sind, werden die Aufgaben in der Aufgabenwarteschlange ausgeführt. Das heißt, es wird gewartet, bis die For-Schleife vollständig beendet ist, bevor die Fun-Funktion ausgeführt wird. Wenn die For-Schleife endet, ist der Wert von i jedoch 6 geworden. Daher ist der Inhalt auf der Konsole immer noch 6, obwohl der Timer 5 Sekunden läuft. (Hinweis: Die For-Schleife muss vom Anfang bis zum Ende einige Mikrosekunden oder Millisekunden dauern. Wenn der Timer eine Sekunde abläuft, ist die For-Schleife bereits abgeschlossen.) Schauen wir uns einen anderen Fall an: für (var i=1; i<=5; i++) { (Funktion() { setTimeout( Funktion Timer() { konsole.log( i ); }, i*1000 ); })(); } Aus dem Betriebsmechanismus von setTimeout können wir erkennen, dass alle externen Hauptprogramme zuerst ausgeführt werden. Obwohl in der for-Schleife ein Abschluss gebildet wird, findet fun keinen tatsächlichen Parameter, sodass es keinen tatsächlichen Unterschied zum ersten Beispiel gibt und weiterhin 5 aufeinanderfolgende 6er ausgegeben werden. Lösung 1: VerschlüsseDie Verwendung von Closures ist ein klassischer Ansatz: für (var i=1; i<=5; i++) { (Funktion(j) { setTimeout( Funktion Timer() { konsole.log( j ); }, j*1000 ); })(ich); } Wir können feststellen, dass das erwartete Ergebnis mit der Ausgabe von 1 bis 5 in der Reihenfolge übereinstimmt. Dies liegt daran, dass die tatsächlichen Parameter innerhalb des Timers stark von i abhängig sind. Durch den Abschluss verbleibt die Variable i im Speicher. Wenn j ausgegeben wird, wird auf den Variablenwert i der externen Funktion verwiesen. Der Wert von i basiert auf der Schleife und die Ausgabe darin wurde bestimmt, als setTimeout ausgeführt wurde. Lösung 2: Struktur aufteilenWir können die Definition und den Aufruf von setTimeout auch in verschiedene Teile aufteilen: Funktion Timer(i) { setTimeout(console.log(i), i*1000); } für (var i=1; i<=5;i++) { Zeitgeber(i); } Die Ausgabe auf der Konsole erfolgt weiterhin in der Reihenfolge 1 bis 5. Lösung 3: letHier ist eine weitere Möglichkeit, dieses Problem mit let von es6 zu lösen: für (sei i=1; i<=5; i++) { setTimeout( Funktion Timer() { konsole.log( i ); }, i*1000 ); } Im Vergleich zum ersten Beispiel ändert dieses Beispiel nur var in let, die Konsole gibt aber nacheinander 1 bis 5 aus. Denn das „let“ am Anfang der For-Schleife bindet i nicht nur an die For-Schleife, sondern bindet es tatsächlich bei jeder Iteration des Schleifenkörpers erneut und stellt so sicher, dass der Wert am Ende der vorherigen Iteration neu zugewiesen wird. Die Funktion() in setTimeout gehört zu einem neuen Bereich. Von var definierte Variablen können nicht in den Ausführungsbereich dieser Funktion übergeben werden. Durch die Verwendung von let zum Deklarieren von Blockvariablen können diese auf diesen Block einwirken, sodass die Funktion die Variable i verwenden kann. Der Parameterbereich dieser anonymen Funktion unterscheidet sich vom Bereich des for-Parameters, und dies wird erreicht, indem dies ausgenutzt wird. Der Gültigkeitsbereich dieser anonymen Funktion ähnelt in gewisser Weise den Attributen einer Klasse und kann von inneren Methoden verwendet werden. Lösung 4: setTimeout dritter Parameterfür (sei i=1; i<=5; i++) { setTimeout( Funktion Timer() { konsole.log( i ); }, i*1000, i ); } Da es sich bei den jedes Mal übergebenen Parametern um Werte aus der For-Schleife handelt, werden 1 bis 5 nacheinander ausgegeben. Oben sind die Details der vier Lösungen für die Verwendung von setTimeout in JS für Schleifen aufgeführt. Weitere Informationen zur Verwendung von setTimeout in JS finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung der Verwendung des gemeinsam genutzten Speichers in Nginx
>>: Detaillierte Installation und Verwendung von RocketMQ in Docker
Inhaltsverzeichnis 1. Installieren Sie den Vue-Vi...
Rendern Beispielcode Heute werden wir das WeChat-...
Ich frage mich, ob Sie jemals über diese Frage na...
Wenn wir SQL zum Extrahieren von Daten verwenden,...
In diesem Artikel wird das kostenlose MySQL-Insta...
Update: Jetzt können Sie auf die offizielle MySQL...
In diesem Artikel werden die Installations- und K...
Excel ist das am häufigsten verwendete Tool zur D...
Ich bin in letzter Zeit beim Erlernen von Docker ...
Inhaltsverzeichnis Überblick Hash-Eigenschaften G...
Vorwort Obwohl manche Liebe auf dieser Welt ihren...
Voraussetzungen Git muss installiert werden Insta...
Lassen Sie uns nun mehrere Situationen zur Steuer...
Vorwort Weil dies ein verteiltes Dateisystem ist,...
Zuvor wurde unter https://www.jb51.net/article/20...