2016-07-29 47 views
3

一些僞同步問題再次...如何通過錯誤處理來完成Ajax請求並檢測整體完成?

我正在尋找最佳實踐來運行一個函數,完成循環內的所有ajax請求之後。

錯誤的例子:

var files = ["file1","file2","File3"]; 
var success = []; 
var error = []; 

for (var i = 0; i < files.length; i++) { 
    $.ajax({ 
     type: "HEAD", 
     url: files[i] 
     }).done(function(){ 
      console.log("file found"); 
      success.push(files[i]); 
      doThisWhenAllFilesChecked(); 
     }).fail(function() { 
      console.log("file not found"); 
      error.push(files[i]); 
      doThisWhenAllFilesChecked(); 
     }) 
} 

錯誤的例子2:同步的,只是爲了說明我正在尋找:

var files = ["file1","file2","File3"]; 
var success = []; 
var error = []; 

for (var i = 0; i < files.length; i++) { 
    $.ajax({ 
     type: "HEAD", 
     async: false, // <-- ! 
     url: files[i] 
     }).done(function(){ 
      console.log("file found"); 
      success.push(files[i]); 
     }).fail(function() { 
      console.log("file not found"); 
      error.push(files[i]); 
     }) 
} 
doThisWhenAllFilesChecked(); 
+1

嘗試jquery $ .when(),它將在所有ajax請求完成後調用成功和錯誤回調。檢查jquery文檔以獲取更多詳細信息 – atul

+0

謝謝! 「$ .when()」看起來很有前途,但還不知道如何在我的情況下使用它,因爲「fail()」,「done()」或「then()」沒有選項可以激發一個函數不管他們的成功或錯誤處理循環後。 我也發現了這個答案,我目前正在看:http://stackoverflow.com/a/18425082/1536850 – Elvis

回答

1

你能做到這 -

var files = ["file1","file2","File3"]; 
    var success = []; 
    var error = []; 
    var k = 0; 
    for (var i = 0; i < files.length; i++) { 
     $.ajax({ 
      type: "HEAD", 
      url: files[i] 
      }).done(function(){ 
       console.log("file found"); 
       k++; 
       success.push(files[i]); 
       doThisWhenAllFilesChecked(); 
      }).fail(function() { 
       k++; 
       console.log("file not found"); 
       error.push(files[i]); 
       doThisWhenAllFilesChecked(); 
      }) 
    } 

    function doThisWhenAllFilesChecked(){ 
     if(k==files.length){ 
     k = 0; 
     //execute code here 
     } 
    } 
+1

謝謝!看起來很好,很容易! :-)我想過以類似的方式使用「while」循環;我只是不確定,如果這是最佳做法......?! – Elvis

+1

我認爲使用這段代碼不會影響性能問題,因爲它只是使用,如果條件來檢查是否應該執行進一步的代碼。 –

+1

我將此標記爲soulution,因爲它符合我一直在尋找的內容,且乾淨且易於使用。謝謝! – Elvis

0

你需要鏈中的所有承諾一起,所以是這樣的:

var promiseArray = [] 
for (var i = 0; i < files.length; i++) { 
    //ajax returns a promise so capture this. 
    promiseArray.push($.ajax({ 
     type: "HEAD", 
     url: files[i] 
     }).done(function(){ 
      console.log("file found"); 
      success.push(files[i]); 
     }).fail(function() { 
      console.log("file not found"); 
      error.push(files[i]); 
     }) 
    ); 
} 

//when can accept an array of deffered objects just call then() after these all return 
$.when(promiseArray).done(doThisWhenAllFilesChecked()); 

在的情況下MUL tiple遞延對象傳遞給 jQuery.when(),該方法返回來自新「主」的Promise 延遲對象,用於跟蹤已通過的所有Deferreds 的聚合狀態。該方法將盡快解決它的主延遲爲 ,因爲所有的延期被解決,或拒絕主延遲爲 ,因爲其中一個延期被拒絕。

注意doThisWhenAllFilesChecked()將運行異步也

+0

我一直在解決這個問題(http://stackoverflow.com/a/ 18425082/1536850),它看起來像一個類似的方法,但是「then()」事件觸發了每次成功並且不等待所有請求完成。 – Elvis

+0

看起來應該完成()然後()。 – Liam

+0

您可能需要返回一個新的承諾,可能來自您的ajax調用中的always(),它需要一點玩弄才能讓所有內容精確匹配 – Liam

0

嘗試這樣的事情。請注意,這只是sudo代碼

var files = ["file1","file2","File3"]; 
var success = []; 
var error = []; 
var promisese = []; 
function xhrCall(fileName){ 
    return $.ajax({ 
     type: "HEAD",   
     url: fileName 
     }); 
} 
function errorCallback(){ 
// do something 
} 
for (var i = 0; i < files.length; i++) { 
    promisese.push(xhrCall(files[i])); 
} 
$.when(promisese).then(doThisWhenAllFilesChecked, errorCallback);