Hier ist Ihr Problem
Sie könnten sich bewusst sein, wie schnell ein for
Schleife läuft (gut es ist sehr schnell), aber das Netzwerk ist überhaupt nicht schnell im Vergleich zu und das ist, was bewirkt, dass Sie problem.Let ich
Sie verwenden $ .getJSON mit URL erklären, die auf offlineName
seinen Wert abhängig ist, aber Sie verwenden offlineName
in Ihrem Erfolg Callback auch. Jetzt für erste req. offlineName
ist "ESL_SC2" jetzt Ajax-Anfrage verwendet es in URL aber wie üblich aufgrund der Netzwerklatenz kommt die Antwort nicht sofort an und Schleife ist jetzt auf zweite Iteration .BUT warten offlineName
IS "OgamingSC2" jetzt !! und wird verwendet werden, wenn Ihr Erfolg Rückruf der ersten Anfrage abgeschlossen ist, aber warten Sie, es gibt noch mehr Einträge, so dass sogar "OgamingSC2" würde später besiegt werden. Darüber hinaus ist die Schleife so unglaublich schnell, dass zu dem Zeitpunkt erste oder zweite Antwort kommt Schleife ist bereits bei der letzten Iteration, so dass nur der letzte Wert Wert (noobs2ninjas) überlebt, der dann im Erfolgsrückruf aller anderen verwendet wird.
Lösung: Die Lösung besteht darin, einen Weg zu finden, mit dem jede Iteration ihren -Wert beibehält und denselben in ihrem entsprechenden Erfolgsrückruf verwendet.Die einfachste Art und Weise zu verwenden let
ist URL
und offlineName
zu erklären, die den Umfang pro Iteration es Wesen begrenzt einen Effekt liefern ähnlich einem Verschluss
https://codepen.io/vsk/pen/LbNpBQ
Das einzige Problem mit dem obigen Code ist, dass let
ist ein neuer Zusatz und älterer Browser unterstützt es nicht gut, so dass die andere Lösung tatsächlich wäre eine Schließung pro Anfrage URL
und offlineName
vorbei
(function(url,name) {
$.getJSON(url, function(data){
if (data.stream !== null){
currChannel = new Channel(data.stream.channel.display_name, data.stream.channel.status);
}
else {
currChannel = new Channel(name, "Offline");
}
outArr.push(currChannel);
});
})(URL,offlineName);
012 zu implementieren
EDIT: Diese self-executing Funktionen genannt werden, und es gibt nichts Besonderes an ihnen nur eine abgekürzte Version des Codes unter
function hello(url,name){ //line #39
//your code
} //ln #53
hello(URL,offlineName); //ln #54
this sehen Sie, dass es läuft perfekt finden würde aber in dem Moment, in dem Sie die Funktion auskommentieren (Zeilennr. 39,53,54) kehrt es wieder auf den alten abgehört behavior.You könnte mich fragen, wie eine einfache Funktion, um die Verhaltensweisen so drastically.Here ist, wie verändern könnte - es ist alles Umfang Ketten auf Basis von
Genau wie Java den JS Der Interpreter (im Folgenden als VM bezeichnet) liest Ihren Code Zeile für Zeile, wenn er die hello
Definition erreicht, die er gerade liest (untersucht Parameter, Return und Inside Code) und geht dann weiter; Jetzt hat es den Ruf Hallo (URL, OfflineName) erreicht; Es führt den Code innerhalb hallo aber dann erkennt es, dass getJson
einen Rückruf hat, der in diesem Moment nicht aufgerufen werden kann, so notiert es in seiner "später aufgerufenen" Liste zusammen mit den Werten aller Variablen in dieser Funktion verwendet zu dieser Zeit [1] .So auch wenn in späteren Schleife Iterationen URL
und offlineName
sind reinitialisiert/neue Werte zugewiesen, sie beeinflussen nicht die Werte in [1] gebunden, da sie keine Beziehung zu ihnen haben, sie sind völlig unterschiedlich Das ist, weil JS Parameter nach Wert (mindestens für primitive Typen) übergibt
Aber die wichtigste Sache über Umfang Ketten ist, dass auch nach der Schleife über die Werte referenziert in getJson
Callback sind immer noch da Einzige Sache ist, Sie können nicht direkt auf sie zugreifen, aber VM kann. Der Grund ist - die letzte Funktion in der Kette ist ein Rückruf (in der Liste aufgenommen) und damit Sinn machen VM muss die Werte überleben, die es benötigt, wenn es ausgeführt wird In der Zukunft nennen Nerds es eine Schließung, wo innere Funktion immer Zugriff auf Dinge in äußeren Funktionen haben wird, auch wenn äußerer Funktionsaufruf vorbei ist und die Steuerung irgendwo anders zurückgekehrt ist. Beachten Sie, dass sogar in Ihren früheren Code-Werten nur Probleme gespeichert wurden wurden sie überschrieben, weil für alle von ihnen nur eine äußere Funktion hatte, dh loadStreams
, aber wenn Sie separate erstellen und aufrufen hello
s jeder erstellt eine separate Umgebung (so etwas wie ein paralleles Universum).
Im Wesentlichen erstellt es Umfangsketten, so dass jede Iteration ihren eigenen Raum haben kann, in dem sie frei von Störungen durch andere ist.
for loop --> hello() --> getJson's inner function
(pro Iteration)
Sie könnten gut mit let
aber zunächst einen Blick auf Kompatibilitätstabelle haben bei http://caniuse.com/#feat=let
Vielen Dank für die Antwort für Anfänger!Es ist interessant zu sehen, dass das Problem mit der Geschwindigkeit des Netzwerks und der Geschwindigkeit der Schleife zusammenhängt (ich bin an Java gewöhnt, ich habe gerade mit js und web dev angefangen). Die erste Lösung ist für mich sinnvoll (ich werde das Schlüsselwort "let" sehen müssen), aber für die zweite Lösung, was macht die Schließung? –
@Thinh Cao Hinzugefügt in Bearbeitung – Viney
Vielen Dank !! –