遇到的一個問題,在for循環中上傳多個文件。每次都去 new XMLHttpRequest.這個上傳是沒問題,但服務器將文件處理後,將執行後的結果返回來的時候,就出現了異常。 html
for(i=0;i<files.length;i++) { f=files[i]; xhr = new XMLHttpRequest(); xhr.open("post", "@Url.Action("Fix")", true); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); var fd = new FormData(); fd.append('file', f); xhr.send(fd); var picsize =f.size / 1024; _html = $("#Lists").html(); _html += '<br/><strong>' + f.name + '</strong>(' + (f.type || "n/a") + ') - ' + picsize.toFixed(2); $("#Lists").html(_html); xhr.onreadystatechange = function () { if(xhr.readyState==4){ if(xhr.status==200){ //do something with xhr.responseText; console.log(xhr.responseText); var data = JSON.parse(xhr.responseText); $("#result").append("<li>" + data.state + ',' + data.file + "</li>"); } } }; }
由於循環過快,在獲取舊的xmlHttpreQuest響應的時候,會被最新生成的 xmlhttpRequest覆蓋掉,雖然服務端返回的結果是正確的,可是上述代碼執行後,顯示的響應結果會亂掉,好比最後提交的文件,它的狀態會被顯示屢次。 瀏覽器
而後就想,可不能夠使用setTimeOut,減緩xmlHttpRequest的生成速度,保證每次的響應被瀏覽器處理後,新的響應再生成。發現這種寫法是得不到延時處理的, 服務器
for(i=0;i<10;i++) { setTimeOut(alert(i)); }for循環無視setTimeOut;
查詢相關資料後,遞歸的用法。 app
var i=0; function al() { i++; if(i<10) setTimeout(function(){alert("i="+i);al()},2000); } al();能夠使問題獲得解決。
試了一下,確實可行。 post
function upload(f) { xhr = new XMLHttpRequest(); xhr.open("post", "@Url.Action("Fix")", true); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); var fd = new FormData(); fd.append('file', f); xhr.send(fd); var picsize =f.size / 1024; _html = $("#Lists").html(); _html += '<br/><strong>' + f.name + '</strong>(' + (f.type || "n/a") + ') - ' + picsize.toFixed(2); $("#Lists").html(_html); xhr.onreadystatechange = function () { if(xhr.readyState==4){ if(xhr.status==200){ //do something with xhr.responseText; console.log(xhr.responseText); var data = JSON.parse(xhr.responseText); $("#result").append("<li>" + data.state + ',' + data.file + "</li>"); } } }; } var length = 0; var i = 0; function doit(files) { if(i<length-1) { setTimeout(function() { alert(i); upload(files[i]); doit(files); i++; },3000); } }
好吧,既然要用遞歸,那就乾脆在xmlHttpRequest內部使用遞歸。
改它的onreadystatechange方法入以下:
xhr.onreadystatechange = function () { if(xhr.readyState==4){ if(xhr.status==200){ //do something with xhr.responseText; console.log(xhr.responseText); var data = JSON.parse(xhr.responseText); $("#result").append("<li>" + data.state + ',' + data.file + "</li>"); if(++i<files.length) upload(files); } } };
問題也能解決。