Funktionen in einer Schleife an setTimeout übergeben: immer der letzte Wert?
Lesezeit: 4 Minuten
Dee2000
Ich versuche, setTimeout zu verwenden, um eine anonyme Funktion auszuführen, an die ich Informationen übergebe, und ich habe Probleme. Diese (fest codierte Version) würde gut funktionieren:
Aber ich versuche, das Hallo und die Welt aus einem Array zu nehmen und sie an die Funktion zu übergeben, ohne (a) globale Variablen zu verwenden und (2) eval zu verwenden. Ich weiß, wie ich es mit Globals oder Eval machen könnte, aber wie kann ich es ohne machen. Folgendes würde ich gerne tun (aber ich weiß, dass es nicht funktionieren wird):
Natürlich Saiten[i] wird aus dem Zusammenhang gerissen. Wie kann ich Zeichenfolgen übergeben[i] in diese anonyme Funktion ohne evalu oder globals?
Siehe stackoverflow.com/questions/3445855/…
– kennytm
21. Juni 11 um 12:17 Uhr
Wenn Sie dieselbe Antwort akzeptieren, kehren Sie immer wieder zurück
– Anand Thanganpan
21. Juni 11 um 12:22 Uhr
mögliches Duplikat des Javascript-Abschlusses innerhalb von Schleifen – einfaches praktisches Beispiel
– Felix Klinge
10. März 13 um 08:28 Uhr
Alnitak
Dies ist das sehr häufig wiederholte Problem „Wie verwende ich eine Schleifenvariable in einem Abschluss?“.
Die kanonische Lösung besteht darin, eine Funktion aufzurufen, die eine Funktion zurückgibt, die an den aktuellen Wert der Schleifenvariablen gebunden ist:
Die äußere Definition function(s) { ... } erstellt einen neuen Geltungsbereich wo s ist an den aktuellen Wert des angegebenen Parameters gebunden – dh strings[i] – wo es für die verfügbar ist innere Umfang.
Die Funktion muss nichts zurückgeben, Sie können das setTimeout in einer haben IIFE
– qwertymk
21. Juni 11 um 12:24 Uhr
@qwertymk das stimmt, aber ich ziehe es vor, nur den Rückruf zu umbrechen, nicht den Anmeldung des Callbacks, nicht zuletzt, weil es das ist, was normalerweise benötigt wird, wenn man dasselbe für DOM-Event-Handler macht.
– Alnitak
21. Juni 11 um 12:25 Uhr
@Alnitak: Ich denke, es ist ziemlich üblich, es auf Svintos Art zu machen. Es ist auch leichter zu verstehen, ohne dem Gehirn des Lesers eine weitere Ebene des Spielraums zu geben
@qwertymk, @Alnitak: Bei beiden Ansätzen erstellen Sie wiederholt eine neue, aber identische Funktionsinstanz innerhalb einer Schleife. Besser IMO ist es, eine benannte Funktion außerhalb der Schleife zu erstellen und diese aufzurufen.
– Benutzer113716
21. Juni 11 um 13:01 Uhr
Fügen Sie einfach einen Bereich um den Aufruf setTimeout hinzu:
Ich kann mich irren, aber das sieht für mich so aus, als ob es unter dem gleichen Problem leiden könnte. Es würde keine Schließung der str-Variablen erzeugen, oder doch? In jedem Fall hinterlässt es eine globale doTimer-Funktion, daher bevorzuge ich die Antwort von Alnitak. Trotzdem danke.
– Dee2000
21. Juni 11 um 12:35 Uhr
Es übergibt eine Kopie der Referenz, also ist es in Ordnung. Das Problem im Original ist, dass es nur ein “i” gibt, das von allen Timeout-Handlern geteilt wird. Und die Funktion muss nicht global sein – sie kann eine lokale Funktion in jeder Funktion sein, in der sich anderer Code befindet.
– Spitze
21. Juni 11 um 12:39 Uhr
Wow, ich glaube, das ist die Am besten Antworten
– iConnor
22. Juni 13 um 23:20 Uhr
warum gehst du nicht einfach als die durch delay -> (i+1) * 1000 ? scheint mir, es ist besser als eine zusätzliche Variable
– vsync
22. Oktober 13 um 12:40 Uhr
@vsync ja das würde sicherlich funktionieren. (Entschuldigung, ich habe dich am Anfang falsch verstanden.)
– Spitze
22. Oktober 13 um 13:09 Uhr
Ciaran
Obwohl nicht so abwärtskompatibel wie einige der anderen Antworten, dachte ich, ich würde eine andere Option aufwerfen, diesmal mit binden()!
Siehe stackoverflow.com/questions/3445855/…
– kennytm
21. Juni 11 um 12:17 Uhr
Wenn Sie dieselbe Antwort akzeptieren, kehren Sie immer wieder zurück
– Anand Thanganpan
21. Juni 11 um 12:22 Uhr
mögliches Duplikat des Javascript-Abschlusses innerhalb von Schleifen – einfaches praktisches Beispiel
– Felix Klinge
10. März 13 um 08:28 Uhr