Javascript jquery延迟的多个ajax调用-如果一个调用失败,有没有办法不拒绝

Javascript jquery延迟的多个ajax调用-如果一个调用失败,有没有办法不拒绝,javascript,jquery,ajax,deferred,Javascript,Jquery,Ajax,Deferred,您好,我正在进行多个ajax调用,希望合并结果 我正在使用以下代码: var args = [ $.ajax({ url:"http://localhost:8080/200/2", type:"get", dataType:"jsonp" }), $.ajax({ url:"http://localhost:8080/200/1", type:"get", dataType:"jsonp" }) ]; jQuery.w

您好,我正在进行多个ajax调用,希望合并结果 我正在使用以下代码:

    var args = [
$.ajax({
    url:"http://localhost:8080/200/2",
    type:"get",
    dataType:"jsonp"
}),
$.ajax({
    url:"http://localhost:8080/200/1",
    type:"get",
    dataType:"jsonp"
})
    ];


    jQuery.when.apply(this, args)
    .done(function(){
        for (var i = 0; i < arguments.length; i++) {
                var singleResult = arguments[i]; 
                console.log("always");
                console.log(singleResult);
                                    //here code to combine results
        }
    })
    .fail(function(){
        for (var i = 0; i < arguments.length; i++) {
                var singleResult = arguments[i]; 
                console.log("fail");
                console.log(singleResult);
        }
    });
var args=[
$.ajax({
url:“http://localhost:8080/200/2",
键入:“获取”,
数据类型:“jsonp”
}),
$.ajax({
url:“http://localhost:8080/200/1",
键入:“获取”,
数据类型:“jsonp”
})
];
jQuery.when.apply(this,args)
.done(函数(){
for(var i=0;i
当两个调用都返回200状态码时,它工作得非常好 但在目前的系统中,有时一次呼叫可能返回500或404 当这种情况发生时,整个承诺被拒绝,完成了 我知道这是默认行为——当一个调用失败时,整个过程都失败了

问:有没有一种简单的方法可以使它以这种方式工作,即单一的失败不会导致整个事情失败 换句话说,假设我打了10个电话,7个成功,3个失败
我希望使用这7个结果调用done,并使用3个结果失败

好的,我通过采用“when”实现并创建自己的版本来解决它 给你

    $.extend({
when2: function( subordinate /* , ..., subordinateN */ ) {
    var i = 0,
        resolveValues = Array.prototype.slice.call( arguments ),
        length = resolveValues.length,

        // the count of uncompleted subordinates
        remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

        // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
        deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

        // Update function for both resolve and progress values
        updateFunc = function( i, contexts, values ) {
            return function( value ) {
                contexts[ i ] = this;
                values[ i ] = arguments.length > 1 ? Array.prototype.slice.call( arguments ) : value;
                if( values === progressValues ) {
                    deferred.notifyWith( contexts, values );
                } else if ( !( --remaining ) ) {
                    deferred.resolveWith( contexts, values );
                }
            };
        },

        progressValues, progressContexts, resolveContexts;

    // add listeners to Deferred subordinates; treat others as resolved
    if ( length > 1 ) {
        progressValues = new Array( length );
        progressContexts = new Array( length );
        resolveContexts = new Array( length );
        for ( ; i < length; i++ ) {
            if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
                resolveValues[ i ].promise()
                    .done( updateFunc( i, resolveContexts, resolveValues ) )
                    //.fail( deferred.reject )
                    // here is the modified line
                    .fail( updateFunc( i, resolveContexts, resolveValues ) )
                    .progress( updateFunc( i, progressContexts, progressValues ) );
            } else {
                --remaining;
            }
        }
    }

    // if we're not waiting on anything, resolve the master
    if ( !remaining ) {
        deferred.resolveWith( resolveContexts, resolveValues );
    }

    return deferred.promise();
}
    });



    jQuery.when2.apply(this, args)
         .then(function(){
            var combinedResults = {};
            for (var i = 0; i < arguments.length; i++) {
                var singleResult = arguments[i]; 
                console.log(singleResult);
                if(singleResult[1]==="success"){
                    for(var serviceName in singleResult[0]){
                        combinedResults[serviceName] = singleResult[0][serviceName];
                    }
                }
            }
            console.log(combinedResults);
        });
$.extend({
when2:函数(从属/*,…,从属*/){
var i=0,
resolveValues=Array.prototype.slice.call(参数),
长度=resolveValues.length,
//未完成的下属数量
剩余=长度!==1 | |(substance&&jQuery.isFunction(substance.promise))?长度:0,
//主控延迟。如果resolveValues只包含一个延迟值,只需使用该值即可。
递延=剩余===1?下级:jQuery.deferred(),
//更新解析值和进度值的函数
updateFunc=函数(i、上下文、值){
返回函数(值){
上下文[i]=这个;
values[i]=arguments.length>1?Array.prototype.slice.call(arguments):值;
如果(值===progressValues){
deferred.notifyWith(上下文、值);
}否则如果(!(-剩余)){
延迟。解析(上下文、值);
}
};
},
ProgressValue、ProgressContext、ResolveContext;
//将听众添加到延迟的下属;将其他人视为已解决
如果(长度>1){
progressValues=新数组(长度);
ProgressContext=新数组(长度);
resolveContexts=新数组(长度);
对于(;i
}))

这样,什么时候才能完成所有的结果 传递给then的参数是数组 每个都包含树值,其中第二个是状态,通过该状态可以确定调用成功或失败

我已经将测试代码放在github上,它有一个小的nodejs服务器,它返回不同的http状态代码用于测试


您可能希望手动处理您的承诺,以始终解决问题,只是有时会出现错误对象或消息。差不多

var deferreds = [];
for(i = 0; i < 10; i++) {
  var defer = $.Deferred();
  deferreds.push(defer)
  $.ajax(/* options */)
  .then(function(res) {
    defer.resolve(res);
  }, function(err) {
    defer.resolve(err);
  })
}

$.when(deferreds)
.then(function() {
  var results = Array.prototype.slice.call(arguments);
  // do something with results
});
var递延=[];
对于(i=0;i<10;i++){
var defer=$.Deferred();
推迟。推送(推迟)
$.ajax(/*选项*/)
.然后(功能(res){
延迟.解决(res);
},函数(err){
延迟。解决(错误);
})
}
$.when(延期)
.然后(函数(){
var results=Array.prototype.slice.call(参数);
//对结果做点什么
});

when then而不是when done如何?无论使用哪一个,问题在于when的默认行为是在多个延迟对象被传递到jQuery的情况下。when方法从一个新的“主”延迟对象返回承诺,该对象跟踪它所传递的所有延迟的聚合状态。该方法将在所有延迟解决后立即解决其主延迟,或在其中一个延迟被拒绝后立即拒绝主延迟,因此,一旦一个调用失败,整个过程就会失败-我正在考虑实现我自己的版本when,它将保留所有res。这不可能真正起作用,由于延迟返回只能处于已解决或已拒绝状态