2017-02-27 4 views
0

Ich habe eine Funktion, die Fragen von einer externen API abruft. Ich brauche mindestens 5 Fragen in einem Array, damit meine Anwendung funktioniert.Wert von zurückgegebenen JSON überprüfen und aktualisieren, wenn falsch

function getCategoryQuestions(){ 
    var questions = {}; 
    var i = 0; 
    for (i; i < 6; i++){ 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     questions[data.name] = data.questions; 
     validQuestionsLength(questions, data.questions) 
    }) 

    } 
    return questions; 
} 

I laufen validQuestionsLength wenn jedes Array Fragen zu überprüfen mindestens 5 Elemente in der Länge ist.

function validQuestionsLength(hash, array){ 
    while (array.length < 5) { 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     hash[data.name] = data.questions 
     array = data.questions; 
    }) 
    console.log(array.length) 
    } 
} 

Ich möchte überprüfen, ob eine Länge des Arrays ist weniger als 5 und wenn ja, werde ich eine neue Ressource aus der URL holen. Ich speichere den neuen Wert im Array und überprüfe dann die Array-Länge dieses neuen Wertes. Ich möchte, dass Daten abgerufen werden, bis die Bedingung erfüllt ist.

Was passiert ist, dass, sobald die validQuestionsLength() -Methode ausgeführt wird und ich eine Array-Länge mit weniger als 5 habe, console.logging das aktuelle Array in einer Endlosschleife bleibt. Ich dachte, ich würde eine neue Ressource in Array auf jeder Schleife speichern.

Ich bin mir nicht sicher, wo mein logischer Fehler passiert.

Ich weiß, dass eine asynchrone Anforderung auftritt, so dass die console.log möglicherweise ausgeführt wird, bevor die Array-Variable zurückgesetzt wird. Ich bearbeitete meine Validierungsfunktion ein getan Rückruf umfassen auszuführen, sobald die async

function validQuestionsLength(hash, array){ 

    if (array.length < 5) { 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     hash[data.name] = data.questions 

     console.log("data is ", data.questions) 
     array = data.questions; 
    }).done(console.log("array is ", array)) 
    } 
} 

Meine Absicht beendet hat war, um die neu geholten Daten zu Array zu speichern. Aber data.questions und das Array (das auf den Wert für data.questions zeigen sollte) sind unterschiedliche Werte. Was macht .done() in diesem Fall?

+0

Also ist Ihr Anruf eine Frage zu einer Zeit oder N zurück? Suchst du nach fünf pro data.name oder fünf gesamt über alle data.name-Daten? Im Moment wird die Art und Weise, wie Sie es Array haben, mit jedem Anruf überschrieben, so dass Ihr Api-Anruf, wenn er fünf Elemente zurückgibt, für immer endlos wird. – Michael

+0

Verwenden Sie 'array.push (data.questions)' anstelle von 'array = data.questions;' Ich bin mir Ihrer JSON-Struktur nicht bewusst, die Sie benötigen, um einen Index hinzuzufügen, wie 'questions [0]' oder etwas – Viney

+0

Wenn Sie die Callback-Funktion falsch eingestellt haben, müssen Sie den Code in die Lambda-Funktion einbetten, wie bei einem Erfolgs-Callback, jetzt haben Sie das Ergebnis result von console.log als Rückruf des ** done ** -Ereignisses. So wird es jetzt noch vor dem Rückruf ausgeführt. –

Antwort

0

EDIT2: Ich habe beispielsweise, wie Sie Ihre beiden Funktionen als gültige Callback-Schleife aussehen, beide Funktionen ähnlich sind, so ist es eine Funktion nur sein kann:

Ich habe mein Skript vereinfacht und für Tests gemacht I mein testResponse php Skript gibt 4 Elemente ["1", "2", "3", "4"] Array einige Male zurück und schließlich gibt es 5 Elemente ["1", "2", "3", "4", "5"] Array.

function getCategoryQuestions(callback){ 
    $.getJSON('http://localhost/testResponse.php', function(data){    
     if(data.questions.length < 5){ 
      getCategoryQuestions(callback); 
     } else {      
      callback(data.questions); 
     } 
    }); 
} 

Der Code wird json von URL erhalten, wenn die Array Frage ist weniger als 5 wird die URL erneut anfordern, bis es wird 5 oder mehr Fragen in Array sein.

Wenn es 5 oder mehr Fragen im Array gibt, wird es sich nicht erneut ausführen, es wird Callback mit Fragen-Array als Argument aufrufen. Diese

ist, wie Sie die Funktion nutzen und Ihre Fragen Array Empfänger:

getCategoryQuestions(function(questions){ 
    console.log(questions); 
}); 

Es ist mehr wie Ajax Fehlerbehandlung durchgeführt, werden.

Edit: getJSON ist async funciton so wird es seine Callback-Funktion aufrufen, nachdem sie die Daten holen wird, so wird der Rückruf später ohnehin durchgeführt werden, auch wenn es nicht zu Ereigniswarteschlange hinzugefügt wird.

Es ist, weil getJSON success callback function Ausführung zur Ereigniswarteschlange hinzugefügt wird, und es nach Sie console.log Ihr Array ausgeführt wird.

Länge

ich einen Test gemacht:

<html> 
    <head> 
     <script 
      src="https://code.jquery.com/jquery-2.2.4.min.js" 
      integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" 
      crossorigin="anonymous"></script> 
    </head> 
    <body> 
     <script> 
      $.getJSON('http://localhost/testResponse.php', function(data){ 
       console.log('Callback'); 
      }); 
      console.log('Script end'); 
     </script> 
     Hello! 
    </body> 
</html> 

und das Ergebnis in der Konsole ist:

Script end 
Callback 

weiter zu erklären, wie es passiert ich zwei Beispiele geben wird 1. Beispiel:

function callCallback(callback){ 
 
\t callback(); 
 
} 
 

 
callCallback(function(){ 
 
\t console.log('Callback'); 
 
}); 
 
console.log('Script end');

produzieren:

Callback 
Script end 

Und die zweite:

function callCallback(callback){ 
 
\t setTimeout(callback, 0); 
 
} 
 

 
callCallback(function(){ 
 
\t console.log('Callback'); 
 
}); 
 
console.log('Script end');

Output gleiche sein wird wie mein getJSON Beispiel so:

Script end 
Callback 

Da die Zeitüberschreitung null ist, wird die Callback-Funktion der Ereigniswarteschlange hinzugefügt, sodass sie nicht sofort ausgeführt wird.

Edit: Auch getJSON ist async funciton so wird es seine Callback-Funktion aufrufen, nachdem sie die Daten holen wird, so wird der Rückruf später ohnehin durchgeführt werden, auch wenn es nicht zu Ereigniswarteschlange hinzugefügt wird.

Verwandte Themen