2009年11月7日星期六

jQuery - 當Javascript Ajax遇上Loop

之前已經略略打過一篇jQuery 的Async和sync的問題:
jQuery – Why Ajax return blank data?

近日我再次遇上近似的問題,我把一段jQuery.ajax 放在一段For...Loop中運行,發現同樣會出現同步問題。
再次上網查證一下,發現原來這不是jQuery的問題,問題在於Javascript原生的XMLHttpRequest和Synchronous問題。

出現問題的程式碼如下:
ASP.NET 2.0 Web Service :
<WebMethod()> _
Public Function returnString(ByVal inputString As String) As String
Return inputString
End Function

網頁上的jQuery Ajax CallBack :
<script type="text/javascript">
$(document).ready(function () { 
for (var i = 1 ;i <= 10;i++)
{
var Options= {
type: "POST",
url: "webservice/DataService.asmx/returnString",
data:'{ inputString: ' + i +'}',
async: "true",
contentType: "application/json; charset=utf-8",
dataType: "JSON",
success: function(response)  { alert(response);  } 
} 
$.ajax(Options); 
}
});
</script>

運行程式後,得出的alert不是順序的12345678910,有可能是4231789...或者9714523。
最後把async設成false就可以解決問題,但是運行時,Browser會呈現硬直狀態。
解決方法雖然是找到了,但是為什麼會這樣?
可以睇睇國外高手的Blog文:
Ajax and javascript don't use threads
Ajax, javascript and threads : the final truth

睇過之後,不難理解為什麼會出現這個同步問題。

4 則留言:

  1. 太早就下定論,Browser 是程式是會改變的
    做一個 window.setTimeout window.clearTimeout 的測試,很快就可以發現這兩個的本身就有 racing condition 的問題 clearTimeout 不能很準確的在把 setTimeout 設定的內容清除

    回覆刪除
  2. 僅管 Browser 本身是使用 Single Thread 如文章所說。API 使用上還是有可能產生 Thread-safe 問題

    如:Sliverlight 支援 Thread, Sliverlight 本身的 API 不一定 Thread-safe

    回覆刪除
  3. 修正: 應該說 設定的內容可被準確清除,但是 setTimeout event 還是有可能多被 fire 一次

    回覆刪除
  4. 抱歉,剛剛回的都離題了,應屬於 setTimeout/clearTimeout 及 Sliverlight 自己的問題,與本文無關

    回覆刪除