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

Posted

技术标签:

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

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

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

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

我已经阅读了this 和this 的帖子,但它没有提供在所有查询完成后可以运行代码的解决方案。

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 中的一元递减原子吗?)。一旦计数器达到零,您就知道所有请求都已完成,您可以处理结果。当然,一旦所有查询完成,您必须缓存查询结果以供以后处理。 复制:***.com/questions/1060539/… 【参考方案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://***.com", 
                "http://***.com", 
                "http://***.com", 
                "http://***.com", 
                "http://***.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 中运行即可)。

【讨论】:

以上是关于并行执行多个 AJAX 请求,并在所有请求完成后运行一个函数的主要内容,如果未能解决你的问题,请参考以下文章

jQuery的$.ajax方法支持同时创建多个异步ajax请求吗?而且这些ajax对象必须是并行处理的

当两个 Ajax 请求被并行调用时,我看到多个加载掩码

jQuery Deferred - 等待多个 AJAX 请求完成 [重复]

Apple Combine框架:如何并行执行多个发布者并等待所有发布者完成?

在循环中执行异步XMLHttpRequests,并在所有请求完成后继续

PHP 请求“排队”