Bildschirmausgabe während Schleifendurchlauf

Sprint

Erfahrenes Mitglied
Hallo zusammen,

ich bin gerade dabei, ein Script für einen Statistikfreak zu schreiben. Dabei kann es vorkommen, daß das Script auch mal mehrere Minuten läuft. Daher wäre es schön, daß sich während des Schleifendurchlaufs am Bildschirm irgendwas tut. Nur werden hier alle Daten erst ausgegeben, wenn schon alles passiert ist.
Javascript:
function getLand(){
    var land = $('#land').val();
    var rueckgabe = '';
    $.ajax({
        type: "POST",
        url: "_pzkunden.php",
        async: false,
        data: {land: land},
        success: function(data){
            rueckgabe = JSON.parse(data);
        }
    });
    $('#gesAnzahl').html('insgesamt zu verarbeiten: '+rueckgabe.length);
    $.each( rueckgabe, function( key, val ) {
        if (val == 'stop')
            alert('fertig');
//            getcsv();
        else
            getDaten(val);
    });
}

function getDaten(kdnr){
    $.ajax({
        type: "POST",
        url: "_pzzaehler.php",
        async: false,
        data: {kdnr: kdnr},
        success: function(data){
            if (data == 'ok')
                $('#kdnrAusgabe').html('aktuelle KdNr: '+kdnr);
            else
                alert('Fehler bei Kdnr '+kdnr);
        }
    });
}

Gibt es da eine Möglichkeit, die Ausgabe auch während des Laufs sichtbar zu machen? Ob es dann lesbar ist oder nicht, ist egal. Hauptsache, es rührt sich was.
 
Lösung
Das Hochladen der Kundennummer als POST-Parameter erfordert nur eine kleine Erweiterung:
Code:
        async function getIt() {
            let formDat = new FormData();
            for (let kdnr = 1; kdnr <= 10; kdnr++) {
                formDat.set('kdnr', kdnr);
                data = await fetch("thread1060-ajax-sync.php", {
                    method: 'post',
                    body: formDat
                }).then(response => {
                    return response.text();
                });
                console.log(data);
                document.querySelector('#kdnrAusgabe').textContent = kdnr;
            }
        }
        getIt();
Wenn Du einen Fehler 404 bekommst, muss noch irgend etwas mit dem Dateinamen oder Pfad...
Hier könnte es Optimierungspotenzial auf der Serverseite geben: Die Anzahl durch die Datenbank mit COUNT ermitteln lassen und nach Kunde gruppieren.
Count läuft schon, aber wenn ich alle auf ein Mal auswerten lasse, rennt die DB ins Timeout. Deshalb der umständliche Weg über HTML.

Was ich noch nicht verstehe: In getDaten steht in der Serverantwort entweder ein String 'ok' oder etwas anderes. Was hat das zu bedeuten?
Reine Faulheit. Ob "error" auswerten oder else ist doch egal.

Gut, dann habe ich das jetzt auch verstanden. Dann werde ich das mal ausprobieren.
 
PPS: Das Problem lässt sich lösen, indem man das moderne async-await verwendet, in dieser Demo wird dann sofort der Wert in #kdnrAusgabe angezeigt:
Code:
    <span id="kdnrAusgabe"></span>
    <script>
        async function getIt() {
            for (let i = 0; i < 10; i++) {
                data = await fetch("thread1060-ajax-sync.php").then(response => {
                    return response.text();
                });
                console.log(data);
                document.querySelector('#kdnrAusgabe').textContent = i;
            }
        }
        getIt();
    </script>
Ich habe das jetzt mal ausprobiert, um das ganze zu verstehen. Der Zähler läuft auch korrekt durch, allerdings bekomme ich dann einen 404 auf die PHP Datei (die ich natürlich erzeugt habe ;)).

Ich habe dann auch mal versucht, mich in das fetch an sich einzulesen, denn irgendwie muß ich ja die Kundennummer hochladen und die Antwort bekommen. Allerdings mit nicht sehr großem Erfolg. Irgendwie erschließt sich mir das noch nicht so wirklich.
 
Das Hochladen der Kundennummer als POST-Parameter erfordert nur eine kleine Erweiterung:
Code:
        async function getIt() {
            let formDat = new FormData();
            for (let kdnr = 1; kdnr <= 10; kdnr++) {
                formDat.set('kdnr', kdnr);
                data = await fetch("thread1060-ajax-sync.php", {
                    method: 'post',
                    body: formDat
                }).then(response => {
                    return response.text();
                });
                console.log(data);
                document.querySelector('#kdnrAusgabe').textContent = kdnr;
            }
        }
        getIt();
Wenn Du einen Fehler 404 bekommst, muss noch irgend etwas mit dem Dateinamen oder Pfad nicht stimmen.
 
Lösung
Ok, wo der 404 herkam, weiß ich nicht. Jetzt ist er jedenfalls weg.

Ich habe die Funktion jetzt mal so umgestrickt, daß sie passen sollte.
Javascript:
        async function getDaten(liste) {
            var rueckgabe = JSON.parse(liste);
            var zaehler = rueckgabe.length;
            let formDat = new FormData();
            for (let i = 0; i < zaehler; i++) {
                formDat.set('kdnr', rueckgabe[i]);
                data = await fetch("_pzzaehler.php",{
                        method: 'POST',
                        body: formDat
                }).then(response => {
                    return response.text();
                });
                console.log(data);
                document.querySelector('#kdnrAusgabe').textContent = i;
            }
        }
Allerdings scheint er die PHP Datei nicht aufzurufen, denn dort sollten auch DB Einträge durchgeführt werden und da passiert nichts.
 
Count läuft schon, aber wenn ich alle auf ein Mal auswerten lasse, rennt die DB ins Timeout.
Ich vermute da auch das dein PHP / SQL Code da etwas optimiert werden muss.
Ich würde alle DB Ausgaben mit JSON rüberschicken und dann mit Js zusammenbauen.

Das eine DB in Timeout geht, kommt selten vor , kann es sein das du irgendwelche sql Abfragen in Schleifen abfragst oder so ?

Können wir mal das PHP Script mal sehen was hinter _pzzaehler.php und _pzkunden.php ist?
 
Guten Morgen zusammen,

das mit den DB Einträgen ist geklärt. Ich hatte da einen Tippfehler im php Script, so daß da keine Daten übernommen wurden.

Ein erster Test mit 100 Kundennummern hat eine Zeit von 20 Sekunden ergeben. Das DB Timeout liegt bei 10 Minuten, so daß bei 3000 Durchläufen das Timeout erreicht wird, und 3000 sind bei vielen Ländern inzwischen drin.

Das ist die _pzkunden.php
PHP:
require "includes/dblog/dblogini.php";

$land = $_POST['land'];

$sql = "select kdnr from kunden where land = '$land' and kdmerkmal = 2";
$erg = mysqli_query($mysqli,$sql);
if (!$erg)
    exit ('<font color="red">Datenbankfehler: '.__FILE__.' Zeile '.__LINE__);
while($zeile = mysqli_fetch_array($erg, MYSQLI_ASSOC)){
    $kdliste[] = $zeile['kdnr'];
}
$kdliste[] = 'stop';
$return = json_encode($kdliste);
die($return);
Und das die _pzzaehler.php
PHP:
require "includes/dblog/dblogini.php";

$kdnr = $_POST['kdnr'];

$sqla = "select
            firmenname,
            (select count(*) from pruefung where kdnr = '$kdnr' and status = 105) as gruen,
            (select count(*) from pruefung where kdnr = '$kdnr' and status = 110) as orange,
            (select count(*) from pruefung where kdnr = '$kdnr' and status = 115) as rot
        from kunden
        where kdnr = '$kdnr'";
$erg = mysqli_query($mysqli,$sqla);
$zeile = mysqli_fetch_array($erg, MYSQLI_ASSOC);

$ges = $zeile['rot'] + $zeile['orange'] + $zeile['gruen'];
if ($ges > 4){
    $sql = "insert into _pzdaten (kdnr, firma, rot, orange, gruen)
                values('$kdnr', '".$zeile['firmenname']."', '".$zeile['rot']."', '".$zeile['orange']."', '".$zeile['gruen']."')";
    $erg = mysqli_query($mysqli, $sql);
    if (!$erg)
        die('error');
}
die('ok');
Der Eintrag des Ergebnisses in die DB erfolgt, um im Nachgang eine csv Datei erstellen zu können.
 
Hast Du denn überhaupt einen Index auf die Kundennummer in der Tabelle pruefung und das Land in der Tabelle kunden?
 
Zuletzt bearbeitet:
Hast Du denn überhaupt einen Index auf die Kundennummer in der Tabelle pruefung und das Land in der Tabellen kunden?
Ich hab da einige Indizes drauf, aber genau da nicht. Hatte sich auch sonst in dem kompletten Paket nicht ausgewirkt. Aber wirkt echt Wunder. :oops:

Danke für den Tip und auch für die Hilfe bei der JS Funktion!
 
Zurück