2012-06-06 74 views
2

我有一個儀表板屏幕,需要在加載時發出大約20個AJAX請求,每個請求返回不同的統計信息。總共需要大約10秒才能返回所有請求。然而在那10秒內,UI幾乎被鎖定。在AJAX調用期間UI無響應

我記得讀過Nick Zakas撰寫的JS書,介紹了在密集操作(使用定時器)期間維護UI響應的技術。我想知道是否有類似的技術來處理我的情況?

* 我試圖避免結合AJAX調用的一些原因

$(".report").each(function(){ 
     var container = $(this) 
     var stat = $(this).attr('id') 
     var cache = db.getItem(stat) 

     if(cache != null && cacheOn) 
     { 
      container.find(".value").html(cache) 
     } 
     else 
     { 
      $.ajax({ 
      url: "/admin/" + stat, 
      cache: false, 
      success: function(value){ 
       container.find(".value").html(value.stat) 
       db.setItem(stat, value.stat); 
       db.setItem("lastUpdate", new Date().getTime()) 
      } 
      }); 
     } 

    }) 
+0

您是否已將$ .ajaxSettings設置爲* asynchronous *?那麼它應該工作。 – Bergi

+0

我相信異步是$ .ajax的默認值? – tpow

+0

異步是默認的:http://api.jquery.com/jQuery.ajax/ – Ian

回答

1

如果你有機會到jQuery的,你可以利用$.Deferred對象同時進行多個異步調用和執行當他們全部解決時回調。

http://api.jquery.com/category/deferred-object/

http://api.jquery.com/deferred.promise/

如果這些回調的正在修改的DOM,你應該存儲在一些臨時位置的變化(如內存中的DOM對象),然後在添加他們都一旦。 DOM操作調用非常耗時。

+0

+1的DOM操作提示。每次我打電話.html()這可能導致迴流(可能重新繪製) – tpow

+0

您可以詳細說明內存中的DOM對象,或發送鏈接?我做了粗略的Google搜索,找不到任何內容..?將初始化包含DIV顯示:無,設置HTML,然後取消隱藏做同樣的事情? – tpow

+0

基本上你想在代碼中建立一個字符串或DOM對象,然後只調用一次DOM操作函數(例如'append'或'appendTo')。 http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly – jbabey

0

我遇到過與SharePoint Web服務密切相關的類似問題 - 您經常需要從多個來源提取數據以爲單個進程生成輸入。

爲了解決這個問題,我將這種功能嵌入到我的AJAX抽象庫中。你可以很容易地定義一個請求,在完成時觸發一組處理程序。但是每個請求都可以用多個http調用來定義。這裏的組分(和詳細的文檔):

DPAJAX at DepressedPress.com

這個簡單的示例創建三個調用一個請求,然後傳遞這些信息,在調用順序,在單個處理程序:

// The handler function 
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) }; 

    // Create the pool 
myPool = DP_AJAX.createPool(); 

    // Create the request 
myRequest = DP_AJAX.createRequest(AddUp); 

    // Add the calls to the request 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]); 

    // Add the request to the pool 
myPool.addRequest(myRequest); 

請注意,與許多其他解決方案不同的是,此方法不會強制執行正在調用的單個線程 - 每個方法仍然可以像環境允許的那樣快速(或緩慢)運行,但只有在全部完成時纔會調用單個處理程序。它還支持超時值的設置和重試嘗試,如果你的服務有點小問題。

對於您的情況,您可以提出一個請求(或與羣組相關的請求 - 例如快速「最需要」請求和更長時間運行的「很高興」請求)調用所有數據並全部顯示同一時間(或多個請求中的塊)完成時。您還可以專門設置要利用的背景對象/線索的數量,這可能有助於解決性能問題。

我發現它非常有用(並且從代碼角度理解起來非常簡單)。沒有更多的鏈接,沒有更多的計數和保存輸出。只需「設置並忘記它」。

哦 - 關於你的鎖定 - 你是否有機會在本地開發平臺上測試它(在瀏覽器的同一臺機器上運行對服務器的請求)?如果是這樣,它可能只是機器本身正在處理您的請求,而不是指示實際的瀏覽器問題。