2011-04-24 133 views
5

我正试图在HTML中使用JQuery完成以下一系列操作。并行执行多个AJAX请求,并在完成所有请求后运行一个函数

  • 的URL列表构造
  • 各URL平行
  • 等待使用$ .getJSON(URL)的所有请求完成或失败请求(404可能发生)
  • 获取所有完成的JSON请求的数据并执行一些操作。

我构建了下面发布的Java脚本代码。它可以正常工作,除非其中一个请求由于404错误而失败:然后,$.when不会运行,因为如果请求失败它会立即中止。你能以某种方式重写ajax-requests,所以它们不会失败,而是返回一个空的源代码?

我已经阅读thisthis文章,但它没有提供解决方案,在所有查询完成后都可以运行代码。

function fetchData() { 
    queries = []; 
    //urls is initialized somewhere else containing all urls 
    for(var url in urls) { 
     queries.push($.getJSON(url)); 
    } 

    $.when.apply(this, queries).done(function() { 
     console.log("Finished all queries, got "+arguments.length+" results"); 
     //Now arguments is a array containing the results of all requests 
    } 

    //function returns instantly, no problem! 
} 
+0

我不是jquery的经验,但似乎你需要查询计数器。即设置一个计数器,以查询您将发送的数量。在成功或相应的错误函数中,递减计数器(在Javascript中是一元递减原子吗?)。一旦计数器达到零,您就知道所有请求都已完成,您可以处理结果。当然,一旦完成所有查询,您将不得不缓存查询结果以供日后处理。 – ewh 2011-04-24 22:10:41

+0

Duplicate:http://stackoverflow.com/questions/1060539/parallel-asynchronous-ajax-requests-using-jquery – joeytwiddle 2015-03-16 22:13:56

回答

2

我可能会做这样的事情:

$(document).ready(function(){ 
    var _q = ['/echo/json/', '/echo/json/', 'mybadurl']; 
    var _d = []; 
    for(u in _q) 
    { 
     $.ajax({ 
      url: _q[u], 
      success: function(data){ 
       pushData(data); 
      }, 
      error: function(x){ 
       pushData(x); 
      } 
     }); 
    } 

    function pushData(d) 
    { 
     _d.push(d); 
     if(_d.length == _q.length) 
     { 
      alert('were done'); 
     } 
    } 
}); 

在这里,你无论从成功错误数据推到阵列_d和测试,以确保在继续之前已经收到的所有答复(alert('were done');)。

当然,您可以通过将包含op状态的对象与有效载荷一起推入_d来实现这一点,但这是一个快速入侵,以展示我最有可能如何执行您所问的问题。

Fiddle here

1

事情是这样的:

function fetchData() { 
    queries = []; 
    //urls is initialized somewhere else containing all urls 
    for(var url in urls) { 
     queries.push($.getJSON(url)); 
    } 

    var returned = 0; 
    for (var i = 0; i < queries.length; i += 1) { 
     call_ajax_somehow(queries[i], function() { 
      console.log("callback called"); 
      returned += 1; 
      if (returned === queries.length) { 
       console.log("Got all " + queries.length + " of them"); 
      } 
     }); 
    } 
} 

你不得不检查如何准确,并调用它如何处理错误jQuery的AJAX规范(即,如何确定错误回调)但修改代码不应太难。

1

像这样的东西应该工作:

function fetchData() { 
    var queriesRun = 0; 
    var allData = []; 

    var urls = ["http://stackoverflow.com", 
       "http://stackoverflow.com", 
       "http://stackoverflow.com", 
       "http://stackoverflow.com", 
       "http://stackoverflow.com/thisdoesnotexist"]; 

    var totalQueries = urls.length; 

    var complete = function(jqXHR, textStatus) { 
     queriesRun++; 
     console.log(queriesRun); 

     if(queriesRun == totalQueries) { 
      console.log("all done"); 
      console.log(allData); 
     } 
    }; 

    for(var i = 0; i < urls.length; i++) { 
     var url = urls[i]; 
     jQuery.ajax({ 
      url: url,   
      success: function(data, textStatus, jqXHR) { 
       allData.push(data); 
      }, 
      complete: complete 
     }); 
    } 
} 

由于complete处理器运行errorsuccess处理后,queriesRun将得到每一个AJAX调用完成时递增。此处理程序还会检查运行的查询数是否等于查询总数。如果是这样,它将与数据一起工作。

我已经在代码中添加了console.log s,所以你可以很容易地看到发生了什么(只需在萤火虫中运行)。