0

嗨,我正在执行多个 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 个结果失败

4

2 回答 2

0

好的,我已经通过采用“何时”实现并创建自己的版本来解决它

    $.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);
        });

});

以这种方式,何时将始终完成所有结果传递给 then 的参数是数组,每个数组都包含树值,其中第二个是您可以确定调用成功或失败的状态

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

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

于 2012-10-25T15:56:52.113 回答
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
});
于 2014-10-24T20:52:11.207 回答