2017-10-16 36 views
4

比方說,我有Ajax調用數組,像這樣:多個異步ajax調用:即使有一些失敗,如何解決所有調用後執行的函數?

// an array of ajax calls 
var callsArray = []; 
callsArray.push(
    $.ajax({ 
    url: '/url1'; 
    cache: false, 
    dataType: 'html' 
    }), 
    $.ajax({ 
    url: '/url2'; 
    cache: false, 
    dataType: 'html' 
    }) 
) 

我事先知道這兩個電話的至少一個會失敗。我想在BOTH調用解決成功或失敗後執行一個函數,並且我還想記錄任何失敗。

這是行不通的:

// NOT APPROPRIATE 
var errors = ''; 
$.when.apply(null, callsArray) 
    .done(function() { 
    console.log('Both calls completed but these urls failed: ' + errors); 
    }) 
    .fail(function() { 
    errors += this.url + ' '; 
    }) 

的問題與上面的是,即使有一個呼叫失敗是.fail執行,而.done只有零話費無法執行。另外,我不能使用.always,因爲只要解決任何呼叫,它就會執行。

所以我在尋找這樣的事情:

// FANTASY CODE 
var errors = ''; 
$.when.apply(null, callsArray) 
    .allCallsResolved(function() { 
    // this executes only when all calls have 
    // returned either a success or a failure 
    // rather than when all calls succeed 
    console.log('All calls completed but these urls failed: ' + errors); 
    }) 
    .everyFailure(function() { 
    // this executes every time a call fails 
    // rather than as soon as any call fails 
    errors += this.url + ' '; 
    }) 
+0

$就已經返回了承諾的對象。看起來像你需要將'$'作爲第一個參數傳遞給'when.apply'而不是'null'。 –

+0

@gp null或$無關 – charlietfl

+0

什麼版本的jQuery?如果它是3+爲每個請求添加一個catch()' – charlietfl

回答

1

你可以在對成功和失敗,然後用Promise.all來驗證所有來電都被做解決了無極包裝每個Ajax調用和/或失敗:

const promises = callsArray.map(function(call) { 
    return new Promise(function(resolve, reject) { 
     call.done(resolve).fail(function(error) { 
      console.log(error); 
      resolve(error); 
     }); 
    }); 
}); 

Promise.all(promises).then(function(values) { 
    console.log(values); 
    //all calls done or failed 
}); 
+0

@Adyson指出我的問題是[重複](https://stackoverflow.com/questions/5824615/jquery-when-callback所有推遲的 - 不再 - 未解決 - 也),因此我將這樣標記這個問題。但是,您的解決方案很好,與另一個問題中提供的解決方案不同。 – mattthew

-1

我做了很久很久以前在JQuery中使用Deferred函數。

 var diff_array = []; 
     var count=0;//you may use counter to know how many Deferred objects are resolved/rejected. 

     //Iterate your callsArray 

     for(i in callsArray){ 

     diff_array[i] = $.Deferred(); 
     //execute each ajax 
     //if ajax fails call reject else resolve/promise. 
     diff_array[i].resolve(); 
     //count++ based on resolve/reject 
     } 

     //any where in the script 
     // write deferred.done() which will be called immediately on resolving corresponding deferred object. 
     diff_array[13].done(
     function() { 
     . 
     . 
      if(count=callsArray.length){ 
      callFinalFunction(); 
      } 
     } 
     ); 
0

var callsArray = []; 
 
callsArray.push(
 
    $.ajax({ 
 
    url: 'https://httpbin.org/status/404', 
 
    cache: false, 
 
    dataType: 'html' 
 
    }), 
 
    $.ajax({ 
 
    url: 'https://httpbin.org/status/200', 
 
    cache: false, 
 
    dataType: 'html' 
 
    }) 
 
); 
 

 
callsArray.forEach((e) => { 
 
    e.done(() => console.log('done')) 
 
    .fail(() => console.log('fail')) 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

相關問題