2

我正在使用以下代码来处理多个 ajax 请求,如下所示:

请求1 开始| 请求1 完成| 请求2 开始| 请求2 完成| ...

这是代码:

var startingpoint = fireRequest(1);
    $.each(types,function(ix,type) 
    {
       startingpoint = startingpoint.pipe( function() 
       {
          alert(startingpoint.status); // undefined
          return fireRequest(type);
        });
    });

fireRequest只是返回 $.ajax(...) 的正确 ajax 函数的 switchcase

当一个请求失败时,我希望链停止。我开始实现它,作为测试,我想提醒 ajax 对象的状态,但它显示“未定义”。我怎样才能获得状态?

4

3 回答 3

1

您尝试实现的行为已经是 .pipe() 方法的行为。它接受两个回调作为参数,并且仅在前一个请求成功的情况下执行完成的回调并沿着链继续。这可以在以下 jsfiddle 中说明:http: //jsfiddle.net/dflor003/Vq2YF/(注意:在具有内置 JSON.stringify 支持和 console.log 支持的浏览器中打开它)

如果您确实想检查请求的状态,它将把状态作为第二个参数传递给 done 回调。更多细节可以在 jQuery 的 API 文档站点上找到:http: //api.jquery.com/deferred.pipe/

于 2012-10-09T14:30:35.453 回答
0

JS示例1

此代码假定您希望在任何一个请求失败(通过 404 或 500 响应,或超时)时中止其他请求,并且不需要评估数据响应以确定业务逻辑故障场景。$.when()

该方法将在所有 Deferred 解析后立即解析其主 Deferred,或者在其中一个 Deferred 被拒绝时拒绝主 Deferred。

    $.when(fireRequest(1), fireRequest(2),fireRequest(3))
  .then(myAllSuccessfulFunc, oneFailedFunc);

function myAllSuccesfulFunc(req1,req2,req3){
//everything returned a 200.
   alert("these are not the droids you are looking for");
};
function oneFailedFunc(req1,req2,req3){
    //* each req looks like [ "not success", statusText, jqXHR ] */
//feel free to check what failed, but I don't know what you need

   req1[2].abort();
   req2[2].abort();
   req3[2].abort();
};

js示例2

您实际上需要在响应中解析成功的数据请求,以查看是否由于来自后端的逻辑而使其他请求失败。

var stop = 4;
//if you are sure fireRequest(x) returns a good promise object, do this:
callNext(fireRequest(1),1);

function callNext(promise, currentIndex){
   promise.done(function(ajaxArgs){
   var jqXHR = ajaxArgs[2];
//replace this with some logic check that makes sense to your app
   if(/error/.test(jqXHR.responseText)){
    //do something
   }else if(currentIndex <stop){
    callNext(fireRequest(currentIndex+1),currentIndex+1);
   }).fail(function(ajaxArgs){
   //server returned a 404, or a 500, or something not a success.
   });
};
于 2012-10-08T03:32:41.873 回答
0

我认为问题在于,$.Deferred类似的东西是为处理异步和并发过程而设计的,所以如果你想让它们按照你描述的方式行事,你总是不得不以某种方式欺骗它们。

如果您想要/需要一个接一个地处理您的调用(使用A JAX),我建议将它们放入一个数组并使用一个简单的递归函数循环遍历该数组,直到所有调用完成或其中一个调用失败。

这基本上可以像这样工作:

var requests = [
  {
  url : '/serviceA'
  data : myParams4ServiceA
  },
  ...
  {
  url : '/serviceZ'
  data : myParams4ServiceZ
  }
];

现在您有一个 AJAX 请求数组,您可以构建一个递归函数,该函数将逐个处理它们:

function work(){

$.ajax(requests[0]).done(function(data){
  //handle data here
  requests.shift(); //request is done and can be removed from the Array, request[0] will now be the next request in the queue

  if (requests.length){
    work(); //function calls itself again if there's still need for it
  } else {
    // we are done!
  }

}).fail(function(e){
  //call failed -> handle error
});

}

work();

有关成功链的示例,请参见this fiddle ,而对于失败的链,请参见this fiddle。

另一种可能性是将 AJAX 调用设置为async : false(请注意,这在 jQuery 1.8+ 中已弃用:“从 jQuery 1.8 开始,不推荐使用 async: false 和 jqXHR ($.Deferred);您必须使用完整/成功/错误回调。 ”这再次指向我们备份),并使用$.when().then().fail()您应用于请求数组的简单链,例如:

$.when.apply($, requests).then(function(){

    $.each(arguments, function(){
        //do stuff with your data
    });

}).fail(function(){

    //handle the error

});

由于您的呼叫现在被阻塞,这也将连续处理它们。也请参阅小提琴

于 2012-10-08T07:34:43.903 回答