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

时间:2012-10-25 14:00:47

标签: 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.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);
        }
    });

当两个调用返回200状态代码时,它完全正常 但在当前系统中,有时一个关闭的呼叫可能会返回500或404 当这种情况发生时,整个承诺被拒绝,并且完成更新 我知道这是默认行为 - 当一个调用失败时,整个事件失败

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

2 个答案:

答案 0 :(得分:0)

好的我已经通过“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);
        });

});

通过这种方式,总是能完成所有结果 传递给的参数是Arrays 每个都包含树值,其中第二个是您可以通过其确定呼叫成功或失败的状态

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

https://github.com/szydan/test-jquery-deffered

答案 1 :(得分:0)

您可能希望手动处理您的承诺以始终解决,有时仅使用错误对象或消息。像

这样的东西
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
});