2016-11-12 3 views
4

Ich arbeite an einer Herausforderung, in der ich Twitch Kanäle anzeigen muss, die offline und online sind. Hier ist die Funktion, die einen Fehler hat:Variable Wert überschrieben in getJSON Funktion

channe_list ist ein Array von Zeichenfolge mit Kanalnamen vorinstalliert. Es ist wie folgt definiert:

var channel_list = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]; 

Mein Code wird einfach durch den channel_list geht, holen die JSON-Daten, und gibt das Ergebnis und erstellen Sie eine neue Instanz des Channel-Objekts, definiert als:

var Channel = function(name, status){ 
    this.name = name; 
    this.status = status; 
} 

Aus irgendeinem Grund wird in meinem Else-Block die Variable "offlineName" IMMER vom letzten Wert des Array channel_list 'noobs2ninjas' überschrieben. Mit anderen Worten, wenn ich eine Instanz der Channel-Klasse im else-Block erstelle, ist "offlineName" immer "noobs2ninjas". Bitte lassen Sie mich wissen, was ich hier falsch mache. Hier ist meine CodePen wenn Sie möchten, einen Blick auf das Ganze nehmen:

https://codepen.io/tcao2/pen/XNbbbm?editors=1010

Antwort

5

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

+1

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? –

+1

@Thinh Cao Hinzugefügt in Bearbeitung – Viney

+1

Vielen Dank !! –

Verwandte Themen