2013-03-28 20 views
11

Ho riscontrato un problema con due richieste AJAX simultanee in esecuzione. Ho uno script PHP che sta esportando i dati su XSLX. Questa operazione richiede molto tempo, quindi sto cercando di mostrare i progressi all'utente. Sto usando AJAX e l'approccio al database. In realtà, sono abbastanza sicuro che funzionasse, ma non riesco a capire perché, non funziona più con nessun browser. Qualcosa è cambiato nei nuovi browser?Due richieste simultanee AJAX non verranno eseguite in parallelo

$(document).ready(function() { 

     $("#progressbar").progressbar(); 

     $.ajax({ 
      type: "POST", 
      url: "{$BASE_URL}/export/project/ajaxExport", 
      data: "type={$type}&progressUid={$progressUid}" // unique ID I'm using to track progress from database 
     }).done(function(data) { 
      $("#progressbar-box").hide(); 
      clearInterval(progressInterval); 
     }); 

     progressInterval = setInterval(function() { 
      $.ajax({ 
       type: "POST", 
       url: "{$BASE_URL}/ajax/progressShow", 
       data: "statusId={$progressUid}" // the same uinque ID 
      }).done(function(data) { 
       data = jQuery.parseJSON(data); 
       $("#progressbar").progressbar({ value: parseInt(data.progress) }); 
       if (data.title) { $("#progressbar-title").text(data.title); } 
      }); 
     }, 500); 

    }); 
  • il progresso sia correttamente aggiornamento nel database di
  • il timer JS sta cercando di ottenere il progresso, posso vederlo in consolle, ma tutte queste richiesta caricamento tutta la durata del primo script, non appena la sceneggiatura termina, queste chiamate di avanzamento ajax vengono caricate

Quindi, perché la seconda chiamata AJAX attende che il primo termini?

+3

Alcune configurazioni di server Web PHP consentono di eseguire contemporaneamente una connessione per sessione. Quindi, se stai usando sessioni, prova un esperimento in una pagina in cui tu (a) inizi una sessione, e poi (b) dormi per 60 secondi. Quindi prova a caricare un numero di istanze di questa pagina nello stesso browser: potrebbero caricarsi una dopo l'altra. – halfer

+0

Hai aggiornato la versione jQuery di recente? –

+1

Inoltre, in generale, più di una operazione AJAX non è la procedura migliore, poiché spreca tempo in chiamate HTTP in eccesso. Puoi unirli in uno e restituire diversi risultati in una stringa JSON? – halfer

risposta

28

Suona come una sessione di blocco problema

Di default PHP scrive i suoi dati di sessione in un file. Quando avvii una sessione con session_start() apre il file per la scrittura e lo blocca per impedire modifiche simultanee. Ciò significa che per ogni richiesta che passa attraverso uno script PHP utilizzando una sessione, è necessario attendere che la prima sessione venga eseguita con il file.

Il modo per risolvere questo problema è quello di cambiare le sessioni PHP non usare i file o per chiudere la scrittura di sessione in questo modo:

<?php 
    session_start(); // starting the session 

    $_SESSION['foo'] = 'bar'; // Write data to the session if you want to 

    session_write_close(); // close the session file and release the lock 

    echo $_SESSION['foo']; // You can still read from the session. 
+2

molto utile !!! grazie –

+0

Ay carumba. Non è un fan delle sessioni PHP, ma sta sviluppando usando Symfony che ne fa un uso completo. Ha senso ma non avrebbe mai indovinato. Buon aiuto! – eggmatters

0

Si potrebbe anche impostare

async: true, 
+0

Questo è per ExtJs che prendo? – Sangoku

2

Dopo un po 'di capelli -pullando, ho trovato uno altro modo che queste richieste AJAX non parallele possano accadere, totalmente indipendenti dalla gestione della sessione di PHP ... Quindi la sto postando qui solo per chi arriva qui attraverso Google con lo stesso problema.

XDebug può causare questo, e non sarei sorpreso se anche Zend Debugger potesse farlo.

Nel mio caso, ho avuto:

  • XDebug installato sul mio locale stack LAMP
  • xdebug.remote_autostart abilitato
  • mio IDE di accettare in ingresso debugger-connessioni, anche se nessun breakpoint erano attivi

Ciò ha causato l'esecuzione sequenziale di tutti i miei test AJAX, a prescindere da cosa. In retrospettiva, ha molto senso (dal punto di vista del debugging) per forzare l'elaborazione sequenziale, ma semplicemente non avevo notato che il mio IDE stava ancora interagendo dietro le quinte.

Dopo aver detto all'IDE di interrompere completamente l'ascolto, sono ripresi i percorsi paralleli e sono riuscito a riprodurre la condizione di gara che stavo cercando.

+0

È molto bello saperlo! – chrislondon

0

Quando si lavora con le API, a volte è necessario inviare più richieste AJAX a diversi endpoint. Anziché aspettare che una richiesta venga completata prima di emettere la successiva, è possibile velocizzare le cose con jQuery richiedendo i dati in parallelo, utilizzando $ di jQuery.quando() funzione:

Run multiple AJAX requests in parallel

0

a.php genera una pagina HTML principale che contiene due simultanee chiamate AJAX per b.php e c.php. Affinché b.php e c.php possano condividere le variabili di sessione, le variabili di sessione devono esistere PRIMA della prima chiamata AJAX. Se questo è vero, a.php e b.php possono cambiare il valore delle variabili di sessione e vedere i rispettivi valori. Pertanto, creare le variabili di sessione con a.php durante la generazione della pagina HTML. (Almeno è così che funziona con Rogers condiviso web hosting.)

1

Attenzione, quella session_write_close() [risposta di chrislondon] potrebbe non risolvere il problema, se hai abilitato il buffer di output (predefinito in PHP 7+). Devi impostare output_buffering = Off in php.ini, altrimenti la sessione non verrà chiusa correttamente.