2017-10-16 54 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>

相关问题