2017-06-21 3 views
-2

Ich versuche, zwei Arrays zu multiplizieren. Ein Array erhält seine Werte durch $('#element').val();, der andere durch Abrufen der Ergebnisse einer GET-Anforderung.Multiplikation von zwei Arten von Arrays

Console Ausgabe:

enter image description here

Hier ist mein Code:

$("#sendeS1").click(function() { 
 
    var i = 1; 
 
    var Q_Values = []; 
 
    var G_Values = []; 
 
    var R_Values = []; 
 

 
    for (i; i <= 20; i++) { 
 
    $.get("bewertung/get/weight/" + i, function(weight) { 
 
     Q_Values[i - 1] = $('#startup_1').find('.' + i).val(); 
 
     G_Values[i - 1] = weight; 
 
     R_Values[i - 1] = Q_Values[i - 1] * G_Values[i - 1]; 
 
     console.log("Q:" + Q_Values); 
 
     console.log("G:" + G_Values); 
 
     console.log("R:" + R_Values); 
 
    }); 
 

 
    $.ajax({ 
 
     url: '/bewertung/1', 
 
     type: 'POST', 
 
     data: { 
 
     startup_id: '1', 
 
     user_id: localStorage.getItem("userid"), 
 
     question_id: i, 
 
     wert: G_Values[i - 1] 
 
     } 
 
    }); 
 
    } 
 
});

+0

Die über 'val()' zurückgegebenen Werte sind immer Zeichenfolgen. Sie müssen sie Zahlen machen, wenn Sie mit ihnen Mathe machen wollen. Der Weg dazu ist in [die Antworten auf diese Frage] (https://stackoverflow.com/q/1133770/215552) erklärt. –

+0

Es gibt eine asynchrone Racebedingung unter den $ $ .get's, die alle zur gleichen Zeit ausgeführt werden. Eine Schleife räumt sie nicht aus. Es ist in Ordnung, alle gets gleichzeitig auszuführen, aber Sie müssen warten, bis alle gets fertig sind, damit die Daten "bereit" sind. Das Lesen einiger asynchroner und/oder ajax Programmier-Tutorials kann helfen, ebenso wie das Verwenden von Promises und 'Promise.all'. – Paul

Antwort

1

es wie folgt tun:

  • Verwenden let für die Variable i im for Block, so ist es eine separate Variable, die noch Bezug genommen werden kann, wenn die Schleife beendet ist und Sie nur dann die Antworten von den get Anrufe bekommen

  • Verwenden + zu konvertieren val() auf eine Zahl (wenn auch in Ihrem Fall ist es nicht unbedingt erforderlich, da die Multiplikation mit dem der Umwandlung on-the-fly ist)

Code:

$("#sendeS1").click(function() { 
    var Q_Values = []; 
    var G_Values = []; 
    var R_Values = []; 

    for(let i = 1; i <= 20; i++){ 
     $.get("bewertung/get/weight/"+i, function (weight) { 
      Q_Values[i-1] = +$('#startup_1').find('.'+i).val(); 
      G_Values[i-1] = weight; 
      R_Values[i-1] = Q_Values[i-1] * G_Values[i-1]; 
      console.log("Q:"+Q_Values); 
      console.log("G:"+G_Values); 
      console.log("R:"+R_Values); 
     }); 
     //...etc 

Warnung: Die Arrays werden noch keine Werte haben, wenn die for Schleife abgeschlossen ist, also nicht davon ausgehen, dass Sie alle Daten direkt nach der Schleife haben. Siehe How do I return the response from an asynchronous call? auf mehrere Möglichkeiten, damit umzugehen.

Eine Möglichkeit, dass nicht die schönste Code ist, aber am einfachsten zu verstehen, ist ein Countdown zu verwenden, so dass Sie wissen, wenn Sie alle Daten haben, und dann eine Funktion aufrufen, die die Weiterverarbeitung tun:

$("#sendeS1").click(function() { 
    var Q_Values = []; 
    var G_Values = []; 
    var R_Values = []; 
    var countDown = 20; 

    for(let i = 1; i <= 20; i++){ 
     $.get("bewertung/get/weight/"+i, function (weight) { 
      Q_Values[i-1] = +$('#startup_1').find('.'+i).val(); 
      G_Values[i-1] = weight; 
      R_Values[i-1] = Q_Values[i-1] * G_Values[i-1]; 
      console.log("Q:"+Q_Values); 
      console.log("G:"+G_Values); 
      console.log("R:"+R_Values); 
      countDown--; 
      if (countDown == 0) processResults(Q_Values, G_Values, R_Values); 
     }); 
     //...etc 

Aber ich würde wirklich empfehlen, in Promises zu schauen. Das ist wirklich der richtige Weg. Zum Glück gibt jQuery $.get ein Versprechen zurück, und diese Versprechen können an $.when weitergegeben werden, die ihre then Methode aufrufen wird, wenn alle diese Versprechen erfüllt worden sind. (Siehe auch What does $.when.apply($, someArray) do?).

$("#sendeS1").click(function() { 
    var Q_Values = []; 
    var G_Values = []; 
    var R_Values = []; 
    var promises = []; 

    for(let i = 1; i <= 20; i++){ 
     promises.push($.get("bewertung/get/weight/"+i, function (weight) { 
      Q_Values[i-1] = +$('#startup_1').find('.'+i).val(); 
      G_Values[i-1] = weight; 
      R_Values[i-1] = Q_Values[i-1] * G_Values[i-1]; 
      console.log("Q:"+Q_Values); 
      console.log("G:"+G_Values); 
      console.log("R:"+R_Values); 
     })); 
     //...etc 
    } 
    $.when.apply($, promises).then(function() { 
     // all is done, process the results here ... 
    }); 

Dieser Code könnte weiter verbessert werden, so dass jedes Versprechen an seinen eigenen Wert zu beheben wäre, und noch nicht das Produkt in ein Array schieben, aber das ist etwas, das Sie vielleicht in sich selbst als eine Übung aussehen kann.

+0

Was ist mit der asynchronen Wettlaufsituation? Wie gezeigt, ist es nicht so schlimm, aber wenn er diese Arrays für etwas Wichtiges verwenden will, muss er wissen, dass das Array "bereit" ist. Und sein veröffentlichter Code tut das nicht. – Paul

+0

Tatsächlich ist das auch ein Problem. Aber da sich die Frage nicht damit befasst ...Ich habe am Ende nur eine Warnung hinzugefügt. – trincot

+0

Das macht den Job. Danke Trincot! Aber jetzt ist die asynchrone Rasse der Schmerz. Hast du eine schnelle Lösung dafür? Ich habe Probleme, deine Links zu verstehen. – Aleks

Verwandte Themen