并行执行许多AJAX请求,并在所有这些请求完成后运行

时间:2011-04-24 21:50:33

标签: javascript jquery ajax json

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

  • 构建网址列表
  • 使用$ .getJSON(url)并行
  • 请求每个网址
  • 等待所有请求完成或失败(可能发生404)
  • 获取所有已完成的JSON请求的数据并执行某些操作。

我构建了下面发布的Java脚本代码。它完美地工作,除非其中一个请求由于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!
 }

3 个答案:

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

答案 2 :(得分: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处理程序之后运行,因此每次AJAX调用完成时queriesRun都会递增。此处理程序还会检查运行的查询数是否等于查询总数。如果是,它将适用于数据。

我在代码中添加了console.log,因此您可以轻松查看正在发生的事情(只需在firebug中运行)。