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 ステータス コードを返す場合、完全に正常に動作しますが、現在のシステムでは、呼び出しの 1 つが 500 または 404 を返す場合があります。呼び出しが失敗する すべてが失敗する

質問: 単一の失敗が全体の失敗の原因にならないように、このように機能させる簡単な方法はありますか? つまり、10 回の呼び出しを実行し、7 回成功し、3 回失敗したとします。 、3 つの結果で失敗します

4

2 に答える 2

0

エラーオブジェクトまたはメッセージを使用して、常に解決するために、promise を手動で処理することをお勧めします。何かのようなもの

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 に答える
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);
        });

});

このように、常にすべての結果で終了する場合、次に渡される引数は配列です。それぞれにツリー値が含まれます。2 番目の値は、呼び出しが成功したか失敗したかを判断できるステータスです。

テストコードを github に配置しました。テスト目的でさまざまな http ステータスコードを返す小さな nodejs サーバーがあります。

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

于 2012-10-25T15:56:52.113 に答える