2012-04-20 52 views
3

花了一點時間去實現這一點,有一個解決方案,我認爲作品相當不錯,在Firefox,但在IE瀏覽器中進行測試時發現,使用異步:假導致瀏覽器被鎖定(停止響應和apprears有冰凍)在通話期間。

要求基本上如下。我提供了一系列用戶可以檢查的複選框。在特定的時間,我調用我的函數'selectedSeriesData()',這個函數使用發送請求到我的服務一個接一個地獲取請求的數據。我特別選擇使用同步,以便在方法執行時向瀏覽器輸出狀態消息和警告。

例如。 「加載數據1/3」,然後選擇「加載數據的2/3」,「加載數據3/3」

當然,我現在才知道,這一定鎖定瀏覽器,以便在IE中的經驗,不僅鎖定瀏覽器,但我試圖顯示的任何消息都沒有顯示。是否有任何簡單的doEvents類似於在每次調用ajax之後可以調用的動作,還是僅僅是重構我的ajax調用的問題。如果是這種情況,根據我的要求提供任何實施建議?

下面是代碼以供參考的簡化的提取物。

function selectedSeriesData() { 

    var seriesData = []; 
    var index = 0; 

    $.each($("input[name='idCheckBox']:checked"), function() { 

     var id = $(this).val(); 

     $("#loadingMessage").text("Loading " + id + "..."); 

      $.ajax({ 
       type: 'POST', 
       async: false, 
       url: '<%: loadSeriesDataPath %>', 
       dataType: 'json', 
       data: { 
        Id: id 
       }, 
       success: function (data) { 
        seriesData[index] = data; 
        index++; 
       }, 
       error: function (xhr, ajaxOptions, error) { 
        $("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>'); 

       } 
      }); 
     } 
    }); 
    return seriesData; 
} 
+0

你是什麼意思的「鎖」? – OptimusCrime 2012-04-20 08:59:56

+0

OptimusCrime,當我說鎖,我的意思是瀏覽器實際上停止響應,並且只有在循環完成執行後纔開始響應。因此,對於使用IE的最終用戶來說,它看起來像瀏覽器崩潰了。 – Arkiliknam 2012-04-20 09:02:12

+0

你能提供jsFiddle的例子嗎? – tarmaq 2012-04-20 09:04:19

回答

1

我認爲我的問題的最佳答案是...你做錯了。如果有人建議(也許這是由於我對它的理解),我沒有任何運氣,所以自己提出了以下答案。

基本上,使用回調來實現一種遞歸排隊。這聽起來對你們來說聽起來很明顯,但它對我來說是新的,我認爲那裏有經驗的jqueryer會同意我的實現(請讓我知道我是否做得對!)

首先,遍歷我的複選框併發出ajax請求,構建一組請求。這擺脫了從原始方法返回我的結果的需要,並開始了一個方法執行鏈,並導致期望的結果。

function selectedSeriesData() { 

    var requests = []; 

    $.each($("input[name='somethingCheckBox']:checked"), function() { 

     var id = $(this).attr('value'); 

     var request = { 
      id: id 
     }; 

     requests.push(request); 

    }); 

    loadRequests(requests); 
} 

從請求的數組,開始呼叫loadRequests其初始化遞歸回調實現,從我的服務加載數據。

function loadRequests(requests) 
{ 
    $("#loader").show(); 
    var seriesData = []; 
    loadRequestAt(requests, 0, seriesData); 
} 

稱爲遞歸方法是loadRequestAt,這使請求的數組的軌跡,一個特定的索引加載此itteration,並且被添加到作爲方法被調用seriesData。匿名方法成功用於構建我的系列數據,用於報告錯誤的錯誤,以及完成最重要的用於開始下一次請求傳輸或完成所有請求時,將結果呈現在屏幕上。

function loadRequestAt(requests, loadAtIndex, seriesData) { 
    var currentRequest = requests[loadAtIndex]; 

    $("#loadingMessage").text("Loading " + currentRequest.id + "..."); 

    $.ajax({ 
     type: 'POST', 
     url: '<%: loadSeriesDataPath %>', 
     dataType: 'json', 
     data: { 
      Id: currentRequest.id 
     }, 
     success: function(data) { 
      seriesData.push(data); 
     }, 
     error: function(xhr, ajaxOptions, error) { 
      $("#warnings ul").append('<li>A communication error occured while attempting to load ' + currentRequest.id'.</li>'); 
     }, 
     complete: function() { 
      var nextIndex = loadAtIndex + 1; 
      if (nextIndex < requests.length) { 
       loadRequestAt(requests, nextIndex, seriesData); 
      } else { 
       $("#loader").hide(); 
       renderResults(seriesData); 
      } 
     } 
    }); 
} 

重要的經驗教訓。使用AJAX(異步JavaScript和XML)時請使用異步調用。請使用提供的匿名回調方法來實現漸進式排隊功能(我確信有一個可接受的名稱,但我不確定)。希望我的學習步驟能夠幫助那些剛接觸jQuery和Ajax電話的人。謝謝!

1

您可以使用jQuery Deferred objects使用異步請求保留,然後選擇「加入」的結果時,所有的人都已經完成。

function selectedSeriesData(cb) { 
    var reqs = []; 
    $("#loadingMessage").text("Loading..."); 
    $("input[name='idCheckBox']:checked").each(function() { 
     var id = $(this).val(); 

     var req = $.ajax({ 
      type: 'POST', 
      url: '<%: loadSeriesDataPath %>', 
      dataType: 'json', 
      data: { 
       Id: id 
      }, 
      error: function(xhr, ajaxOptions, error) { 
       $("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>'); 

      } 
     }); 
     reqs.push(req); 
    }); 
    $.when(reqs).done(function() { 
     cb($.makeArray(arguments)); 
    }); 
} 

現在,您只需通過一個回調到您的函數,然後將接收只要他們都成功完成包含來自AJAX請求的所有結果的陣列。

注:$.when該文檔是不是,如果它接受包含deferreds單一陣列中真正明確。如果它不工作嘗試$.when.apply($, reqs)而不是$.when(reqs)

+0

這聽起來太棒了。我會馬上檢查出來! – Arkiliknam 2012-04-20 10:04:39

+0

延期對象沒有任何運氣,但並非100%確定它是否適合我的問題。我確實想出了一個我現在發佈的asyn解決方案,如果社區同意或不同意,我會感興趣。 – Arkiliknam 2012-04-20 16:36:36