同时执行多个 AJAX 请求,并在所有请求完成后运行一个函数。

6
我正在尝试使用JQuery在HTML中完成以下操作序列。
  • 构建URL列表
  • 使用$.getJSON(url)并行请求每个URL
  • 等待所有请求完成或失败(可能会出现404错误)
  • 获取所有已完成JSON请求的数据并执行某些操作。
我编写了下面发布的JavaScript代码。它完美地工作,除非其中一个请求由于404错误而失败:然后, $.when 不运行,因为它立即中止。您可以以某种方式覆盖ajax请求,使其不会失败,而是返回空源吗?
我已经阅读了这篇文章这篇文章,但它们没有提供一种解决方案,可以在所有查询完成后运行代码。
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方面经验不是很丰富,但似乎你需要查询计数器。即设置一个计数器来记录你将要发送的查询数量。在成功或相应的错误函数中,递减计数器(在Javascript中一元递减是原子操作吗?)。一旦计数器达到零,你就知道所有请求都已完成,可以处理结果了。当然,在所有查询完成后,你还需要缓存查询结果以供以后处理。 - ewh
请注意,此链接已被重复:https://dev59.com/PnNA5IYBdhLWcg3wL6sc - joeytwiddle
3个回答

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');)。
当然,您可以通过将包含操作状态和有效负载的对象推送到_d中来使其更智能化,但是这只是一个快速的hack示例,演示了我最可能实现您要求的方式。 此处有Fiddle

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

我已经在代码中添加了console.log,这样您就可以轻松地看到发生了什么(只需在firebug中运行它)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接