2012-03-02 9 views
5

Ho una barra di progresso jQueryUI che dovrebbe mostrare la percentuale di una query eseguita. Oracle ha una bella tabella di sistema che ti permette di vedere operazioni che dureranno più di 10 secondi. Sto cercando di effettuare chiamate $ .ajax scaglionate a questa query per aggiornare la barra di avanzamento.jQuery loop AJAX per aggiornare jQueryUI ProgressBar

Il problema è, posso ottenere sia i passanti a fare richieste di fuoco rapido, senza alcun tempo di attesa, o semplicemente ritardare l'intero JavaScript da eseguire.

comincio la prima richiesta cliccando il mio tasto "Esegui" in una finestra di jQueryUI.

$("#dlgQuery").dialog({ 
    buttons: { 
     Execute: function() { 
      $(this).dialog("close"); 
      StartLoop(); 
     } 
    } 
}); 

che sto cercando di costruire sia la funzione StartLoop() o fare una funzione ricorsiva GetProgress(). Idealmente, avrò una variabile pubblica var isDone = false che fungerà da indicatore per quando terminare il ciclo o interrompere la chiamata in modo ricorsivo alla funzione.

Per semplicità ho appena fatto un ciclo statico che esegue 100 volte:

function StartLoop(){ 
    for (var i = 0; i < 100; i++) { 
     GetProgress(); 
    } 
} 

Ed ecco la mia richiesta di esempio Ajax:

function GetProgress() { 
    $.ajax({ 
     url: "query.aspx/GetProgress", 
     success: function (msg) { 
      var data = $.parseJSON(msg.d); 
      $("#pbrQuery").progressbar("value", data.value); 
      //recursive? 
      //GetProgress(); 

      //if (data.value == 100) isDone = true;     
     } 
    }); 
} 

Quindi quello che ho trovato è, finora:

setTimeout(GetProgress(), 3000) in StartLoop() blocca Javascript e la finestra di dialogo non si chiude (presumo, perché attenderà fino a quando la query non viene completata).

This uno, pausecomp(3000) fa più o meno la stessa cosa.

Se io chiamo uno di questi nella funzione "successo" della mia richiesta AJAX, esso viene ignorato (probabilmente perché si sta cominciando un'altra chiamata in modo asincrono).

Sono un po 'bloccato qui, tutto l'aiuto sarebbe apprezzato, grazie.

+1

domanda interessante. :) Non riesco a pensare ad una buona risposta. Hai provato a utilizzare setInterval? Cosa è successo quando hai provato il metodo ricorsivo? –

+0

Ricevo richieste/risposte a fuoco rapido. – tedski

risposta

16

Invece di setTimeout(GetProgress(), 3000), si vorrebbe:

function StartLoop(){ 
    for (var i = 0; i < 100; i++) { 
     setTimeout(GetProgress(), 3000*i); 
    } 
} 

In caso contrario, tutte le 100 saranno sparare dopo 3 secondi. Invece, vuoi 0, 3000, 6000, 9000, ecc., Ad es.3000*i;

Meglio, è possibile utilizzare setInterval e clearInterval:

var myInterval = setInterval(GetProgress(), 3000); 

e nella richiamata, effettuare:

$.ajax({ 
    url: "query.aspx/GetProgress", 
    success: function (msg) { 
     var data = $.parseJSON(msg.d); 
     $("#pbrQuery").progressbar("value", data.value); 

     if (data.value == 100) { 
      isDone = true; 
      clearInterval(myInterval); 
     }   
    } 
}); 

clearInterval si fermerà di chiamare GetProgress() di nuovo. L'utilizzo del metodo setInterval significa che non devi sapere quanti loop di polling hai bisogno in anticipo. Continuerà semplicemente finché non avrai finito.

O meglio ancora, è possibile chiamare GetProgress() dal callback Ajax, con il vantaggio che sarà solo il polling di nuovo una volta che avete una risposta dalla query:

function GetProgress() { 
    $.ajax({ 
     url: "query.aspx/GetProgress", 
     success: function (msg) { 
      var data = $.parseJSON(msg.d); 
      $("#pbrQuery").progressbar("value", data.value); 

      if (data.value == 100) { 
       isDone = true; 
      } else { 
       setTimeout(GetProgress(), 2000); 
      } 
     } 
    }); 
} 

Poi basta chiamare GetProgress() una volta per avviare il ciclo.

+0

la tua seconda soluzione aveva senso per me prima, ma per qualche motivo sta ignorando il setTimeout nella funzione di successo – tedski

+0

Ottenuto per funzionare .. usato la tua seconda soluzione, con setInterval e clearInterval. leggi una bella spiegazione qui: http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/ Grazie! – tedski

+0

Fantastico! Sono contento che tu abbia funzionato. –

0

Credo che ciò che si vuole fare è chiamare di nuovo la funzione getProgress quando completa.

dovrai fare questo aggiungendo il parametro 'completa' alla chiamata AJAX

$.ajax({ 
    //this is where your stuff already is 
    ,complete: getProgress() 

    //we add a timeout so it doesn't run everytime it completes, only when we want to update the progress bar. 
    ,timeout: 10000 //this is 10 seconds 
}); 

Questo è un metodo comunemente indicato come 'polling'.

+0

sembra promettente, ma sfortunatamente penso che "timeout" si riferisca a quanto tempo prima farà cadere la richiesta Ajax. Sto ancora ricevendo un ciclo di richieste di fuoco rapido. – tedski

+0

Sì hai ragione. La risposta di Jeff B è esattamente ciò che stavo per modificare anche la mia - quindi, invece, mi sto rovinando la sua. – Ohgodwhy