Javascript 多个异步ajax调用:即使某些调用失败,如何在所有调用都解决后执行函数?

Javascript 多个异步ajax调用:即使某些调用失败,如何在所有调用都解决后执行函数?,javascript,jquery,ajax,Javascript,Jquery,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' }) ) 我事先知道这两个电话中至少有一个

假设我有一系列ajax调用,如下所示:

// an array of ajax calls
var callsArray = [];
callsArray.push(
  $.ajax({
    url: '/url1';
    cache: false,
    dataType: 'html'
  }),
  $.ajax({
    url: '/url2';
    cache: false,
    dataType: 'html'
  })
)
我事先知道这两个电话中至少有一个会失败。我想在两个调用都被解析为成功或失败后执行一个函数,我还想记录任何失败

这行不通:

// 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只在零个调用失败时执行。我也不能使用.始终,因为它会在任何调用解析后立即执行

因此,我在寻找这样的东西:

// 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 + ' ';
  })

您可以将每个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
});

很久以前,我在Jquery中使用了延迟函数

     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();
           }
        }
        );
var callsArray=[];
callsArray.push(
$.ajax({
网址:'https://httpbin.org/status/404',
cache:false,
数据类型:“html”
}),
$.ajax({
网址:'https://httpbin.org/status/200',
cache:false,
数据类型:“html”
})
);
callsArray.forEach((e)=>{
e、 完成(()=>console.log('done'))
.fail(()=>console.log('fail'))
});

$。ajax已经返回promise对象。看起来您需要将
$
作为第一个参数传递给
when.apply
而不是
null
@gp null或$不相关什么版本的jQuery?如果是3+的话,在每一个上添加一个
catch()
request@charlietfl,是的,你是对的,大约$0或null。我误解了这个问题。这可能会有所帮助:@Adyson已经指出我的问题是a,因此我将把这个问题标记为a。但是,您的解决方案很好,并且与另一个问题中提供的解决方案不同。