2012-03-02 19 views
5

Tengo una barra de progreso jQueryUI que debe mostrar el porcentaje de una consulta realizada. Oracle tiene una buena tabla de sistema que le permite ver operaciones que tomarán más de 10 segundos. Estoy intentando hacer llamadas escalonadas de $ .ajax a esta consulta para actualizar la barra de progreso.jQuery bucle AJAX para actualizar jQueryUI ProgressBar

El problema es que puedo obtener los bucles para hacer solicitudes rápidas sin tiempo de espera o simplemente retrasar la ejecución de todo el JavaScript.

Empiezo la primera solicitud haciendo clic en el botón "Ejecutar" en el cuadro de diálogo jQueryUI.

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

estoy tratando de construir, ya sea la función StartLoop() o hacer una función recursiva GetProgress(). Idealmente, tendré una variable pública var isDone = false para que actúe como mi indicador de cuándo finalizar el ciclo o detener de forma recursiva la función.

Por simplicidad acabo de hacer un bucle estática que ejecuta 100 veces:

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

Y aquí está mi muestra de 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;     
     } 
    }); 
} 

Así que lo que he encontrado es, hasta el momento:

setTimeout(GetProgress(), 3000) en StartLoop() se bloquea el Javascript, y el cuadro de diálogo no se cierra (supongo, porque esperará hasta que la consulta se complete).

This uno, pausecomp(3000) hace casi lo mismo.

Si llamo a cualquiera de estos en la función "éxito" de mi solicitud AJAX, se ignora (probablemente porque está comenzando otra llamada asincrónicamente).

Estoy un poco atrapado aquí, cualquier ayuda sería apreciada, gracias.

+1

pregunta interesante. :) No puedo pensar en una buena respuesta. ¿Has probado usar setInterval? ¿Qué pasó cuando probaste el método recursivo? –

+0

Recibo solicitudes/respuestas de disparo rápido. – tedski

Respuesta

16

En lugar de setTimeout(GetProgress(), 3000), usted quiere:

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

De lo contrario, todos los 100 disparará al cabo de 3 segundos. En cambio, quiere 0, 3000, 6000, 9000, etc., es decir3000*i;

Mejor, podría utilizar setInterval y clearInterval:

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

y en la devolución de llamada, hacer:

$.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 habrá que deje de llamar GetProgress() nuevo. Usar el método setInterval significa que no tiene que saber cuántos lazos de encuesta necesita por adelantado. Simplemente continuará hasta que haya terminado.

O mejor aún, puede llamar GetProgress() de la devolución de llamada Ajax, con la ventaja de que sólo se sondear de nuevo una vez que haya una respuesta de su consulta:

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); 
      } 
     } 
    }); 
} 

A continuación, sólo llamar GetProgress() una vez para iniciar el ciclo

+0

su segunda solución tenía sentido para mí anteriormente, pero por alguna razón está ignorando el setTimeout en la función de éxito – tedski

+0

Lo tengo que trabajar ... usé su segunda solución, con setInterval y clearInterval. lea una buena explicación aquí: http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/ ¡Gracias! – tedski

+0

¡Impresionante! Me alegro que lo hicieras funcionar. –

0

Creo que lo que quiere hacer es volver a llamar a la función getProgress cuando se complete.

podría hacer esto añadiendo el parámetro 'completo' a la llamada 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 
}); 

Este es un método comúnmente conocido como 'polling'.

+0

esto parece prometedor, pero desafortunadamente creo que el "tiempo de espera" se refiere a cuánto tiempo antes de que caiga la solicitud de Ajax. Todavía estoy obteniendo un ciclo de solicitud de disparo rápido. – tedski

+0

Sí, tienes razón. La respuesta de Jeff B es exactamente lo que iba a modificar la mía también, así que, en cambio, estoy subiendo la suya. – Ohgodwhy