2012-07-05 280 views
0

因此情況如下:jQuery:暫停或延遲功能

我有一個遞歸的,異步的AJAX調用,它正在從服務器拉數據。這個遞歸調用在用戶登錄時只發生一次。 我有另一個需要AJAX調用才能導航的頁面(基本上是一個延遲加載的樹)。當第一個AJAX調用正在發生時,這些其他調用需要一段時間才能完成,並且由於第一個調用可能發出多達2000個請求,所以此延遲有時會相當長。

基本上我想實現的是在進行其他調用時「暫停」遞歸調用。僞代碼:

function recursiveAjax(){  
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // do stuff 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      recursiveAjax(); 
     } 
    }); 
} 

function navigationAjax(){  
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // pause recursiveAjax(); 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      // resume recursiveAjax(); 
     } 
    }); 
} 
+0

這非常瘋狂。嘗試在超時塊中包裝遞歸調用,例如成功:setTimeout(function(){recursiveAjax();},500); - 這應該爲其他呼叫留出空間,並且不那麼瘋狂。 – Mahn 2012-07-05 13:26:01

+0

看看[jQuery deferreds](http://api.jquery.com/category/deferred-object/) – elclanrs 2012-07-05 13:27:13

回答

1

由於您可能不希望同時發生這兩個請求,因此讓遞歸方法可以執行一個或另一個。當你想導航呼叫設置一個標誌,讓遞歸方法做到這一點的請求下一次迭代:

var navigationCall = false; 

function recursiveAjax(){ 
    if (navigationCall) { 
    navigationCall = false; 
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     error : function(xhr, ajaxOptions, thrownError) { 
     // handle errors 
     }, 
     success : function(data) { 
     //conditions 
     recursiveAjax(); 
     } 
    }); 
    } else { 
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
     // do stuff 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
     // handle errors 
     }, 
     success : function(data) { 
     //conditions 
     recursiveAjax(); 
     } 
    }); 
    } 
} 

function navigationAjax(){ 
    navigationCall = true; 
} 

注意:您可能想添加一個window.TimeOut呼叫做遞歸限制請求的流服務器。與人眼可以看到更改相比,更經常地調用服務器毫無意義。

+0

遞歸調用在後臺構建數據樹 - 用戶永遠不會看到它。如果這棵樹不需要存在,它會使我的生活變得更容易,但是它確實存在,並且每次都需要這樣做。謝天謝地,這只是一個臨時措施,但看到我的應用程序表現如此糟糕,仍然讓我感到很痛苦。 – Squishy 2012-07-05 13:54:41

+0

而且工作正常。仍然是一個非常沉重的表現,但它的速度是以前的兩倍,所以至少有這種情況。非常感謝 – Squishy 2012-07-05 14:05:49

+0

爲什麼不限制recursiveAjax()的速率;火災?每500毫秒運行一次可能會在性能方面產生巨大差異。 – Mahn 2012-07-05 18:52:00

2

最簡單的方法:

window.recurse = true; 
function recursiveAjax(){  
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // do stuff 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      if(window.recurse){ 
       recursiveAjax(); 
      } 
     } 
    }); 
} 

function navigationAjax(){  
    window.recurse=false; 
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // pause recursiveAjax(); 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      window.recurse=true; 
      recursiveAjax(); 
     } 
    }); 
} 
+0

很好的答案,但它並沒有明顯的性能差異。 navigationAjax調用仍然延遲幾秒鐘。 – Squishy 2012-07-05 13:51:49

+0

@Squishy:你不會看到任何性能差異,唯一的區別是你不讓客戶端代碼發出另一個遞歸請求,而​​不是讓服務器隊列發出請求。但是,在等待遞歸請求的響應時,您仍在執行導航請求,因此導航請求仍將由服務器排隊。 – Guffa 2012-07-05 14:02:27

1

JavaScript是一種異步的語言,所以你可以做這樣想你想只有像其他評論回調(見上文)。但考慮一下你的問題,大多數情況下最好在Web上使用異步。你真的想要這個嗎?

+0

不,我不知道 - 但是我的老闆呢。就像我剛纔提到的那樣,它是一個臨時性的措施,至少這個代碼不會在野外長期存在。 – Squishy 2012-07-05 14:07:00