2012-03-02 67 views
5

我有一個jQueryUI進度條,應該顯示完成查詢的百分比。 Oracle有一個很好的系統表,可以讓你看到需要10秒以上的操作。我試圖對這個查詢進行交錯的$ .ajax調用,以刷新進度條。jQuery AJAX循環刷新jQueryUI ProgressBar

問題是,我可以在沒有任何等待時間的情況下讓循環快速啓動請求,也可以延遲整個JavaScript執行的時間。

我通過在jQueryUI對話框中單擊我的「執行」按鈕來啓動第一個請求。

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

我試圖建立無論是StartLoop()功能或進行遞歸GetProgress()功能。理想情況下,我將有一個公共變量var isDone = false作爲我何時終止循環或停止遞歸調用函數的指示器。

爲了簡單起見,我剛剛作出了一個靜態的循環執行100次:

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

這是我的樣品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;     
     } 
    }); 
} 

所以我發現的是,到目前爲止:

setTimeout(GetProgress(), 3000) in StartLoop()凍結Javascript,並且對話框沒有關閉(我假設,因爲它會一直等到查詢完成)。

This one,pausecomp(3000)做了很多相同的事情。

如果我在我的AJAX請求的「成功」函數中調用其中之一,它會被忽略(可能是因爲它正在異步啓動另一個調用)。

我有點卡在這裏,任何幫助將不勝感激,謝謝。

+1

有趣的問題。 :)我想不出一個好的答案。你有沒有嘗試過使用setInterval?當你嘗試遞歸方法時發生了什麼? – 2012-03-02 22:05:05

+0

我得到速射請求/迴應。 – tedski 2012-03-02 22:15:39

回答

16

相反的setTimeout(GetProgress(), 3000),你會想:

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

否則,所有的100將在3秒後火了。相反,你想要0,3000,6000,9000等,即3000*i;

更好,你可以使用setIntervalclearInterval

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

,並在回調,這樣做:

$.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將再次調用GetProgress()停止。使用setInterval方法意味着你不必知道你需要多少輪詢循環。它會一直持續到你完成。

或者更好的,你可以調用GetProgress()從Ajax回調,其優點是,一旦你有從您的查詢的響應,只會再次輪詢:

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

然後,只需調用GetProgress()一次啓動循環。

+0

您的第二個解決方案對我來說早些時候有意義,但由於某些原因,它忽略了成功函數中的setTimeout – tedski 2012-03-02 22:23:07

+0

瞭解它的工作..使用第二個解決方案,使用setInterval和clearInterval。在這裏閱讀一個很好的解釋:http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/ 謝謝! – tedski 2012-03-02 22:41:01

+0

太棒了!很高興你有它的工作。 – 2012-03-02 22:45:20

0

我相信你想要做的是當它完成時再次調用getProgress函數。

你會通過添加「完成」參數去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 
}); 

這就是通常所說的「投票」的方法做到這一點。

+0

這看起來很有希望,但不幸的是我認爲「超時」是指在它將放棄ajax請求之前多久。我仍然得到一個快速請求循環。 – tedski 2012-03-02 22:12:36

+0

是的,你說得對。傑夫B的回答正是我要修改我的答案 - 所以相反,我正在上升他的。 – Ohgodwhy 2012-03-02 22:21:01