【问题标题】:Perform many AJAX requests in parallel, and run a function after all of them complete并行执行多个 AJAX 请求,并在所有请求完成后运行一个函数
【发布时间】:2011-08-12 00:30:49
【问题描述】:

我正在尝试在 HTML 中使用 JQuery 完成以下操作序列。

  • 构造了一个url列表
  • 这些 url 中的每一个都是使用 $.getJSON(url) 并行请求的
  • 等待所有请求完成或失败(可能会发生 404)
  • 获取所有已完成的 JSON 请求的数据并做一些事情。

我构建了下面发布的 JavaScript 代码。它完美地工作,除非其中一个请求由于 404 错误而失败:然后,$.when 不会运行,因为如果请求失败,它会立即中止。您能否以某种方式覆盖 ajax 请求,使它们不会失败,而是返回一个空源?

我已经阅读了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!
 }

【问题讨论】:

  • 我在 jquery 方面没有那么丰富的经验,但您似乎需要查询计数器。 IE。为您将发送的查询数量设置一个计数器。在成功或相应的错误函数中,递减计数器(Javascript 中的一元递减原子吗?)。一旦计数器达到零,您就知道所有请求都已完成,您可以处理结果。当然,一旦所有查询完成,您必须缓存查询结果以供以后处理。

标签: javascript jquery ajax json


【解决方案1】:

我可能会这样做:

$(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');)。

当然,您可以通过将包含操作状态的对象连同有效负载一起推送到 _d 来使这更智能,但这是一个快速破解,以展示我最有可能如何去做你正在做的事情问。

Fiddle here

【讨论】:

    【解决方案2】:

    类似这样的:

    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 规范,了解如何准确调用它以及如何处理错误(即如何指定错误回调),但修改代码应该不会太难。

    【讨论】:

      【解决方案3】:

      这样的事情应该可以工作:

      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 处理程序之后运行,所以每次AJAX 调用完成时queriesRun 都会递增。此处理程序还检查运行的查询数是否等于查询总数。如果是,它将与数据一起工作。

      我在代码中添加了console.logs,这样您就可以轻松查看发生了什么(只需在 firebug 中运行即可)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-30
        • 1970-01-01
        • 1970-01-01
        • 2021-05-07
        • 2017-02-13
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        相关资源
        最近更新 更多