【问题标题】:jquery-ajax multiple callsjquery-ajax 多次调用
【发布时间】:2012-10-03 11:49:30
【问题描述】:

我正在使用以下代码来处理多个这样的 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 对象的状态,但它显示“未定义”。如何获取状态?

【问题讨论】:

  • 这听起来可能很傻,但你为什么不把你的 AJAX 调用设置为 async: false(取消 AJAX 中的 A)?还是我把你的问题弄错了?
  • 如果我输入 'Async: false',它的行为确实和这里一样,但是当 1 失败时如何停止请求呢?我觉得我的问题中的代码更正确
  • 您可以简单地拥有一个包含您刚刚处理的请求的数组。如果成功则继续下一项,如果呼叫失败则中断。尽管如此,我同意非异步 AJAX 毫无意义。你看过 $.when 了吗?
  • 是的。这是一个简洁的功能,但在 .when() 中我无法从之前的通话结果中看到状态。也许我做错了,因此我的问题:)

标签: jquery ajax jquery-deferred


【解决方案1】:

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

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

【讨论】:

  • 砰!回答了我想要的问题和一个工作示例。非常感谢!
【解决方案2】:

JS示例1

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

只要所有的 Deferred 解决,或拒绝 master 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.
   });
};

【讨论】:

    【解决方案3】:

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

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

    这基本上会像这样工作:

    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 one 了解失败的链。

    另一种可能性是将 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
    
    });
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多