2011-09-30 131 views
5

最近我開發了一個項目,我在單個aspx頁面發送多個ajax請求。我也提出了一個計時器,這個請求發生間隔5秒。 一切似乎都正常工作,直到突然響應混淆。我知道我可以用一個請求做同樣的事情,但我想知道爲什麼會發生這種情況。我環顧了互聯網,但我還找不到任何解決方案。我現在實際上採用了這種編碼方式,就像做出一個帶有多個結果的請求一樣,但是我想知道如何做出多個ajax請求,但是響應不會混淆。 這是我的示例代碼:Ajax多個請求在同一時間

$(document).ready(function() { 
     var a = setInterval("request1()", 5000); 
     var b = setInterval("request2()", 5000); 
    }); 

function request1() { 

     $.ajax({ 
      url: 'ajaxhandler.aspx?method=method1' , 
      beforeSend: function (xhr) { 
       xhr.overrideMimeType('text/plain; charset=utf-8'); 
      }, 
      success: function (data) { 
        alert(data); 
      } 

     }); 
    } 


function request2() { 

     $.ajax({ 
      url: 'ajaxhandler.aspx?method=method2' , 
      beforeSend: function (xhr) { 
       xhr.overrideMimeType('text/plain; charset=utf-8'); 
      }, 
      success: function (data) { 
        alert(data); 
      } 

     }); 
    } 
+1

混合起來?在異步環境中,您無法保證哪個呼叫會先返回。 – Joe

回答

4

如果需要的要求,以便發生,你不應該使用AJAX(第一個「一」是「異步」)。

爲了解決這個問題,您可以在回調中調用request2()來獲得第一個請求的「成功」。

function request1() { 
    $.ajax({ 
     url: 'ajaxhandler.aspx?method=method1' , 
     beforeSend: function (xhr) { 
      xhr.overrideMimeType('text/plain; charset=utf-8'); 
     }, 
     success: function (data) { 
       request2(); 
     } 

    }); 
} 
2

這不是JavaScript錯誤,它是因爲您在同一時間調用單個頁面而搞砸了。如果你有兩個服務器端頁面爲你的兩個AJAX文件,那麼它會沒事的。嘗試爲您創建兩個不同的aspx文件,以便讓不同的methods將它們一起呼叫。

但這不是一個好的做法。爲什麼不將該方法作爲參數發送,並針對不同的方法在aspx文件中有條件?然後,如果您同時使用兩種(或更多)方法,則只需通過一次調用即可將這兩種方法發送到服務器。您將保存一個HTTP標頭併爲您的通話延遲通話。

function requestAll() { 

     $.ajax({ 
      url: 'ajaxhandler.aspx' , 
      data: ['method1', 'method2'], 
      beforeSend: function (xhr) { 
       xhr.overrideMimeType('text/plain; charset=utf-8'); 
      }, 
      success: function (data) { 
        alert(data); 
      } 

     }); 
    } 
1

正如已經指出,你不能保證的順序返回結果。但是,如果有必要能夠確定這一點,你可以想見,創建一個唯一的標識符,每進行一次異步請求,然後相應地理清傳入的響應。

我看到這樣一個解決方案很有用的例子是在擊鍵時執行操作(例如onkeyup)。在做這樣的事情時,您可能希望對時間戳,版本號或類似內容進行編碼,以便保證某種順序。如果用戶試圖搜索「test」,則有可能在「te」的響應之前返回「tes」的自動填充響應。如果您只是簡單地覆蓋自動填充數據,那麼顯然這不會是您想要的行爲,因爲您可能會顯示當前搜索標記的結果不正確。

對時間戳(或唯一ID,計數器,版本號,密鑰等)進行編碼將允許您檢查此項以驗證您是否擁有最新的響應,或者如果您使用時間戳對結果進行排序需要保證訂單等。

2

下面的函數將接受一個JSON請求的url數組,並在所有請求完成後用一組結果調用回調。它可以很容易地適應非JSON的使用。

這個想法是在數據到達時將傳入的響應隱藏到數組中,然後只在所有結果都進入時才調用回調。這種方法是批量更新DOM的好方法,並且避免每個計時器都有一個計時器你想要更新的節點。

function multi_getJSON(urls, callback) 
{ 
    // number of ajax requests to wait for 
    var count = urls.length; 

    // results of individual requests get stuffed here 
    var results = []; 

    // handle empty urls case 
    if(count === 0) 
    { 
     callback(results); 
     return; 
    } 

    urls.forEach(function(url, index) 
    { 
     $.getJSON(url, function(data) 
     { 
      results[index] = data; 
      count = count - 1; 

      // are we finished? 
      if(count === 0) 
      { 
       callback(results); 
      } 
     }); 
    }); 
}