2009-09-10 5 views
46

Sono un programmatore JavaScript/jQuery da principiante a intermedio, quindi gli esempi concreti/eseguibili sarebbero molto apprezzati.jQuery Polling AJAX per risposta JSON, gestione basata su risultato AJAX o contenuto JSON

Il mio progetto richiede l'utilizzo di AJAX per il polling un URL che restituisce JSON contenente o contenuti da aggiungere al DOM, o un messaggio { "status": "in attesa"} che indica che il backend sta ancora lavorando sulla generazione una risposta JSON con il contenuto. L'idea è che la prima richiesta all'URL attiva il backend per iniziare a costruire una risposta JSON (che viene poi messa in cache), e le chiamate successive controllano se questo JSON è pronto (nel qual caso è fornito).

Nel mio script, ho bisogno di interrogare questo URL a intervalli di 15 secondi fino a 1:30 minuti, e procedere come segue:.

  • Se i AJAX richiesta restituisce un errore, terminare lo script .
  • Se la richiesta AJAX ha esito positivo e il contenuto JSON contiene {"status": "in attesa"}, continuare il polling.
  • Se la richiesta AJAX ha esito positivo e il contenuto JSON contiene contenuto utilizzabile (ad esempio qualsiasi risposta valida diversa da {"status": "in sospeso"}), visualizzare quel contenuto, interrompere il polling e terminare lo script.

Ho provato alcuni approcci con scarso successo, ma ho la sensazione che siano tutti più cauti di quanto debbano essere. Ecco una funzione scheletrica che ho usato con successo per fare una singola richiesta AJAX in un momento, che fa il suo lavoro se ho contenuti fruibili dalla risposta JSON:

// make the AJAX request 
function ajax_request() { 
    $.ajax({ 
    url: JSON_URL, // JSON_URL is a global variable 
    dataType: 'json', 
    error: function(xhr_data) { 
     // terminate the script 
    }, 
    success: function(xhr_data) { 
     if (xhr_data.status == 'pending') { 
     // continue polling 
     } else { 
     success(xhr_data); 
     } 
    }, 
    contentType: 'application/json' 
    }); 
} 

Tuttavia, questa funzione attualmente non fa nulla a meno che non riceve una risposta JSON valida contenente contenuti utilizzabili.

Non sono sicuro di cosa fare sulle linee che sono solo commenti. Sospetto che un'altra funzione debba gestire il polling e chiamare ajax _ request() secondo necessità, ma non conosco il modo più elegante per ajax _ request() per comunicare i suoi risultati alla funzione polling in modo che possa rispondere appropriatamente.

Qualsiasi aiuto è molto apprezzato! Per favore fatemi sapere se posso fornire ulteriori informazioni. Grazie!

risposta

46

È possibile utilizzare un timeout semplice per chiamare in modo ricorsivo ajax_request.

success: function(xhr_data) { 
    console.log(xhr_data); 
    if (xhr_data.status == 'pending') { 
    setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again 
    } else { 
    success(xhr_data); 
    } 
} 

Stick un controllo contatore intorno quella linea e hai un numero massimo di sondaggi.

if (xhr_data.status == 'pending') { 
    if (cnt < 6) { 
    cnt++; 
    setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again 
    } 
} 

Non è necessario eseguire alcuna operazione nella funzione di errore se non si desidera attivare un avviso o qualcosa del genere. il semplice fatto che l'errore impedirà il richiamo della funzione di successo e l'eventuale attivazione di un altro sondaggio.

+0

Grazie, Joel! Questo ha funzionato per me - lo apprezzo. – Bungle

+1

SetTimeout() blocca l'esecuzione del resto dello script durante i periodi di ritardo? –

+1

No. 'setTimeout()' specifica un intervallo di tempo in futuro per un blocco di codice da eseguire. Il resto dello script verrà bloccato solo quando scade il timeout e viene eseguito il codice. – Joel

3

Fuori della parte superiore della mia testa:

$(function() 
{ 
    // reference cache to speed up the process of querying for the status element 
    var statusElement = $("#status"); 

    // this function will run each 1000 ms until stopped with clearInterval() 
    var i = setInterval(function() 
    { 
     $.ajax(
     { 
      success: function (json) 
      { 
       // progress from 1-100 
       statusElement.text(json.progress + "%"); 

       // when the worker process is done (reached 100%), stop execution 
       if (json.progress == 100) i.clearInterval(); 
      }, 

      error: function() 
      { 
       // on error, stop execution 
       i.clearInterval(); 
      } 
     }); 
    }, 1000); 
}); 
+0

Grazie per la risposta! Ho trovato che la soluzione di Joel Potter ha funzionato meglio nella mia situazione - questo è utile, però. – Bungle

4

vi ringrazio molto per la funzione. È un po 'buggy, ma ecco la soluzione. La risposta di roosteronacid non si ferma dopo aver raggiunto il 100%, perché c'è un uso errato della funzione clearInterval.

Ecco una funzione di lavoro:

$(function() 
{ 
    var statusElement = $("#status"); 

    // this function will run each 1000 ms until stopped with clearInterval() 
    var i = setInterval(function() 
    { 
     $.ajax(
     { 
      success: function (json) 
      { 
       // progress from 1-100 
       statusElement.text(json.progress + "%"); 

       // when the worker process is done (reached 100%), stop execution 
       if (json.progress == 100) clearInterval(i); 
      }, 

      error: function() 
      { 
       // on error, stop execution 
       clearInterval(i); 
      } 
     }); 
    }, 1000); 
}); 

La funzione clearInterval() è becomming l'id intervallo come parametro e quindi tutto va bene ;-)

Acclamazioni Nik

0

Puoi usa la funzione javascript setInterval per caricare i contenuti ogni 5 secondi.

var auto= $('#content'), refreshed_content; 
    refreshed_content = setInterval(function(){ 
    auto.fadeOut('slow').load("result.php).fadeIn("slow");}, 
    3000); 

Per i vostri Reference

Auto refresh div content every 3 sec