2017-07-10 8 views
0

Ich habe zwei Ajax Anrufe. Der erste Aufruf besteht darin, eine Datei zu lesen und sie in der Datenbank (mysql) zu speichern, und am Ende einer for-Schleife setzen sie eine Sitzungsvariable des "Status" wie das Intervall. Der zweite Aufruf gibt die Sitzungsvariable zurück.Ajax Anrufe nicht parallel

das ist mein Javascript-Code:

var interval = null; 
function test(data) { 
    var i = 0; 
    interval = setInterval(function() { 
     $.ajax({ 
      url: '/admin/movies/progress', 
      type: "GET", 
      async: true, 
      dataType: "text", 
      success: function (data) { 
       console.log(data); 
       $('#saveFileProgressBar').width(data[0]); 
      }, 
      error: function (XMLHttpRequest, textStatus, errorThrown) { 
       toastr.error('error progressbar', 'Download File'); 
      } 
     }); 
     i++; 
     if(i == 5){ 
      clearInterval(interval); 
     } 
    }, 500); 

    $.ajax({ 
     url: '/admin/movies/1', 
     type: "GET", 
     async: true, 
     dataType: "text", 
     success: function (data) { 
      console.log(data); 

     }, 
     error: function (XMLHttpRequest, textStatus, errorThrown) { 
      toastr.error('error', 'Download File'); 
     } 
    }); 
} 

dies mein Laravel 5,4 Code:

// Mapped to mysite.com/admin/movies/progress 
public function getProgress() { 
    return Response::json(array(Session::get('progress'))); 
} 

// Mapped to mysite.com/admin/movies/1 
public function postGenerate() { 
    // getting values from form (like $record_num) 
    Session::put('progress', 0); 
    Session::save(); // Remember to call save() 

    for ($i = 1; $i < 100; $i++) { 
     sleep(1); 
     Session::put('progress', $i); 
     Session::save(); // Remember to call save() 
    } 

    return "done"; 
} 

enter image description here

/////// EDIT ///////

mein neuer PHP-Code:

public function getProgress() { 
    $rawData = file_get_contents('plugins/elFinder-2.1.25/files/data/progressFile.json'); 
    $cacheData = json_decode($rawData, true); 
    return $cacheData; 
} 

public function postGenerate() { 
    // getting values from form (like $record_num) 
    for ($i = 0; $i < 10; $i++) { 
     $data['progress'] = $i; 
     $fres = fopen('plugins/elFinder-2.1.25/files/data/progressFile.json', 'w'); 
     fwrite($fres, json_encode($data)); 
     fclose($fres); 
     sleep(1); 
    } 
    return "true"; 
} 

mein Javascript-Code:

var interval = null; 
function test() { 
    var i = 0; 
    interval = setInterval(function() { 
     $.ajax({ 
      url: '/admin/movies/progress', 
      type: "GET", 
      async: true, 
      dataType: "text", 
      success: function (data) { 
       console.log(data); 
       $('#saveFileProgressBar').width(data.progress); 
      }, 
      error: function (XMLHttpRequest, textStatus, errorThrown) { 
       toastr.error('Es ist ein Fehler aufgetreten beim Auslesen der Datei', 'Download File'); 
      } 
     }); 
     i++; 
     if(i == 5){ 
      clearInterval(interval); 
     } 
    }, 500); 

    $.ajax({ 
     url: '/admin/movies/1', 
     type: "GET", 
     async: true, 
     dataType: "text", 
     success: function (data) { 
      console.log(data); 

     }, 
     error: function (XMLHttpRequest, textStatus, errorThrown) { 
      toastr.error('Es ist ein Fehler aufgetreten beim Auslesen der Datei', 'Download File'); 
     } 
    }); 
} 
+0

wenn ich die async Linien kommentieren oder diese auf false gesetzt dann noch den Fortschritt Anruf zu warten, bis der andere Anruf – Damlo

+3

@Damlo Check out jQuery '$ .when', wird dies beendet ist erlauben Sie, einen Rückruf nur einmal auszuführen, wenn 1 oder mehr Ajax-Anrufe abgeschlossen wurden. Dies ist ein Versprechen. – Ohgodwhy

+0

@ Ohgodwhy ich bin mir nicht sicher, ob ich $ .when richtig verstehe. Kannst du mir ein Beispiel mit meinem "Problem" geben? – Damlo

Antwort

1

Anfragen

Requests

Antwort

Response

Hallo,

Ich lief gerade einen Test des Skripts und Antwort ist in der imag es oben. Das erste Bild ist eine Liste von AJAX-Anfragen. Die grünen sind abgeschlossene Anfragen und die graue Anfrage ist noch in Bearbeitung. Das zweite Bild zeigt ein Protokoll der Antwort der Anrufe in der Reihenfolge, in der die Anfrage abgeschlossen wurde (die erste abgeschlossene Anfrage wird oben angezeigt und so weiter ..).

in den Bildern auf den Aufruf erstes AJAX bezieht sich (natürlich umbenannt ich es /set-progress statt /admin/Film/1).Die anschließende zweite AJAX-Aufrufe markiert sind 2 - 6 und /progress = /admin/Filme/progress.

Ich nehme an, Ihr Problem ist, dass die nachfolgenden (zweiten Aufruf) Anforderungen nicht ausgeführt werden, bis die erste abgeschlossen ist. Aus meiner Prüfung, die ich als falsch erachte. Wir können klar sehen, dass die erste Anfrage noch aussteht, während andere Anfragen abgeschlossen sind. Wir können also sagen, dass Ihre Anfragen parallel laufen.

Für Ihren Fall kann es nur ein Problem geben (die unwahrscheinliche; vorausgesetzt, Sie hätten genug Ressourcen, um eine kleine Anfrage zu bearbeiten) und das heißt, Ihr Server ist nicht mehr Ressourcen. es bedeutet, dass es nicht genug Speicher hat, um die zweiten Anrufe zu dienen. seit der ersten Anruf ging durch und der Server hat keine Ressourcen, kann es keine weiteren Anfragen verarbeiten und damit die zweite Anrufe bis die erste Anfrage abgeschlossen hat blockiert. Also, Ihre ersten Anruf oder jede andere laufende Aufgabe/Prozess/Anfrage verbraucht Ihre Server-Ressourcen, daher blockiert weitere Anfragen.

Lesen der Kommentare und der vorherigen Antwort über die gesperrte Datei, so dass parallele Anfragen nicht an den Server gesendet werden können oder der Server keine parallelen Anfragen akzeptieren kann. Diese Aussage ist ebenfalls falsch. Sitzungsdateien sind jedes Mal gesperrt, wenn die Sitzungsdatei aktualisiert wird. Dies ist jedoch nicht darauf zurückzuführen, dass der Browser mehrere Anforderungen gleichzeitig sendet.

Wenn die Datei nicht verfügbar ist/existiert nicht bei jeder Anfrage, wirft Laravel einfach einen 500-Fehler. Das beigefügte Bild zeigt die Antwort für den Fall, dass die Datei nicht verfügbar ist.

File not available

Wenn die Datei gesperrt ist beim Schreiben, die Antwort (zu Fortschritt zu nennen) ist einfach leer. Das heißt, die Datei existiert, aber ihr Inhalt ist momentan nicht verfügbar. Das Bild unten zeigt eine Beispielantwort.

File locked during write operation

Wenn diese Antwort, die Sie nicht erfüllt, folgen Sie bitte diesen Links. Sehen Sie, ob sie helfen könnten. Link 1 und Link 2.

Meine Testumgebung:

  • PHP v7.0.13
  • Apache v2.4.23
  • Laravel v5.4
  • jQuery v3.2.1
  • Firefox v54.0.1
  • Plattform Windows 10
+0

ok ich habe "mein Problem" gefunden ich habe keine Apache verwendet .. Ich habe verwendet: "php artisan serve" ... und jetzt habe ich es mit einem apach server getestet, dann klappt es! – Damlo

1

Statt Sitzung Verwendung reguläre Datei zu verwenden. Sitzungsdateien sind für jede eindeutige Sitzung gesperrt, bis das Skript beendet ist. Also kann es nicht parallel laufen. Sie können die Daten in einer einfachen Datei speichern und darauf zugreifen.

Um von der Cache-Datei

json Datenstruktur für die gesamte Sitzung verwenden können und analysieren bestimmte Fortschrittsdaten oder Sie
$rawData = file_get_contents('data/progressFile.json'); 
$cacheData = json_decode($rawData, true); 

Schreib wie

$data['progress'] = 100; 
     $fres = fopen('data/progressFile.json', 'w'); 
     fwrite($fres, json_encode($data)); 
     fclose($fres) 

Sie lesen raus kann eine separate Datei für ech-Fortschrittsdaten verwenden. Wenn Sie eine große Datei verwenden, müssen Sie möglicherweise flock() verwenden, um die Datei während des Schreibens zu sperren.

+0

Ich habe es versucht, aber es ist bis zum selben. Die Datei wird im ersten Ajax-Aufruf aktualisiert. aber die anderen Ajax Anrufe immer noch warten, dass der erste Anruf beendet ist – Damlo

+0

Was hast du probiert? Ich habe dieses Setup für eine Anwendung und es funktioniert gut. Stellen Sie außerdem sicher, dass Sie die Datei fclose() so früh wie möglich speichern. file_put_content() hält die Sperre. Sie sollten fopen() verwenden – varuog

+0

ich habe meinen Beitrag mit dem neuen PHP und Javascript bearbeitet – Damlo