2012-03-02 18 views
5

Mam pasek postępu jQueryUI, który powinien pokazywać procent wykonanego zapytania. Oracle ma ładną tabelę systemową, która pozwala zobaczyć operacje, które zajmie więcej niż 10 sekund. Próbuję wykonać rozłożone wezwania $ .ajax do tego zapytania, aby odświeżyć pasek postępu.jQuery Pętla AJAX do odświeżenia jQueryUI ProgressBar

Problem polega na tym, że mogę albo uzyskać pętle, aby wykonać szybkie żądania pożaru bez żadnego czasu oczekiwania, albo po prostu opóźnić wykonanie całego skryptu JavaScript.

Uruchamiam pierwsze żądanie, klikając przycisk "Wykonaj" w oknie dialogowym jQueryUI.

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

Próbuję zbudować zarówno funkcję StartLoop() lub dokonać rekurencyjną GetProgress() funkcję. Najlepiej byłoby, gdyby publiczna zmienna miała być wskaźnikiem, kiedy przerwać pętlę lub zatrzymać rekurencyjne wywoływanie funkcji.

Dla uproszczenia właśnie popełnił statycznej pętli, która wykonuje 100 razy:

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

A oto moja prośba próbki 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;     
     } 
    }); 
} 

Więc co znalazłem to, do tej pory:

setTimeout(GetProgress(), 3000) w StartLoop() zawiesza JavaScript, a okno dialogowe nie zamyka się (zakładam, ponieważ będzie czekać, aż zapytanie zostanie wykonane).

This jeden, pausecomp(3000) robi to samo.

Jeśli zadzwonię do któregokolwiek z nich w funkcji "sukces" mojego żądania AJAX, zostanie ono zignorowane (prawdopodobnie dlatego, że rozpoczyna asynchronicznie inne połączenie).

Trochę utknąłem tutaj, każda pomoc będzie doceniona, dzięki.

+1

ciekawe pytanie. :) Nie mogę wymyślić dobrej odpowiedzi. Czy próbowałeś w ogóle używać setInterval? Co się stało, gdy wypróbowałeś metodę rekursywną? –

+0

Otrzymuję szybkie żądania/odpowiedzi. – tedski

Odpowiedz

16

Zamiast setTimeout(GetProgress(), 3000), co chcesz:

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

W przeciwnym razie, wszystkie 100 będzie wystrzelić po 3 sekundach. Zamiast tego potrzebujesz 0, 3000, 6000, 9000 itd., Tj.3000*i;

Lepsze, można użyć setInterval i clearInterval:

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

aw zwrotnego, należy:

$.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 zatrzyma go przed wywołaniem GetProgress() ponownie. Korzystanie z metody setInterval oznacza, że ​​nie musisz wiedzieć, ile pętli odpytywania potrzebujesz z góry. To będzie po prostu trwało, dopóki nie skończysz.

Albo jeszcze lepiej, można zadzwonić GetProgress() z ajax zwrotnego, z tą zaletą, że będzie ankiecie tylko kolejny raz masz odpowiedź zapytanie:

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

Następnie wystarczy zadzwonić GetProgress() raz zainicjuj pętlę.

+0

Twoje drugie rozwiązanie miało dla mnie sens wcześniej, ale z jakiegoś powodu ignoruje setTimeout w funkcji sukcesu – tedski

+0

Gotowy do pracy ... użył twojego drugiego rozwiązania, z setInterval i clearInterval. przeczytaj ładne wyjaśnienie tutaj: http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/ Dzięki! – tedski

+0

Awesome! Cieszę się, że to działa. –

0

Uwierzę, że to, co chcesz zrobić, to ponownie wywołać funkcję getProgress po jej zakończeniu.

Można by to zrobić poprzez dodanie 'kompletny' param do ajax rozmowy

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

Jest to metoda powszechnie zwany 'odpytywania'.

+0

to wygląda obiecująco, ale niestety myślę, że "timeout" odnosi się do tego, jak długo przed upływem żądania ajax. Nadal dostaję pętlę żądania szybkiego uruchomienia. – tedski

+0

Tak, masz rację. Odpowiedź Jeffa B jest dokładnie tym, co miałem zamiar zmodyfikować również - więc zamiast tego go ulepszam. – Ohgodwhy