Ü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
Angenommen, es gibt zwei Linux-Server A und B, un...
Inhaltsverzeichnis Veränderungen im Lebenszyklus ...
Inhaltsverzeichnis 1. Grundprinzipien 2. Spezifis...
Vor Kurzem musste ich das Projekt für die Mitglie...
Flex(彈性布局) in CSS kann das Layout einer Webseite ...
Vorwort Im Grunde verwenden Programmierer am Arbe...
In diesem Artikel erfahren Sie mehr über einen pr...
Keepalive wird häufig zum Caching in Vue-Projekte...
Inhaltsverzeichnis Zusammenfassung Einfaches Beis...
MySQL Zeile zu Spalte, Spalte zu Zeile Der Satz i...
Inhaltsverzeichnis Umfang Globaler Umfang Funktio...
Was ist ein Selektor? Die Rolle des Selektors bes...
Wie unten dargestellt: SELECT Anzahl(DISTINCT(a.r...
Inhaltsverzeichnis 1. Trigger-Einführung 1. Was i...
Hintergrund Es gibt einen Tencent Linux Cloud-Hos...