在处理后中断ajax调用的每个循环

Breaking out of each loop of ajax calls after handling

本文关键字:循环 调用 ajax 处理 中断      更新时间:2023-09-26

我一直无法跟踪我的SO帐户!

问题:

我的工具允许用户在过去10年中每年点击以显示一组数据。并非所有年份都有数据,但他们仍然可以选择每年浏览,并可能收到"无记录"的消息。

在初始页面加载时,我只想显示最近的数据年份,然后在剩余年份停止发送ajax调用。目标是在用户可能只关心最近一年的情况下,防止在页面加载时发送10个ajax调用。

最初,我的方法是将所有年份都放入一个$.each()循环中,其中包含ajax调用,在该年的ajax调用返回数据的第一年,它将脱离循环。所以我尝试了一些类似的东西:

function getData(path,id,year) {
        return $.ajax({
            url: "includes/"+path,
            data: { id: id, year: year },
            dataType:"json"
        });
    }
$.each([ 2015,2014,2013,2012,2011 ], function( k, v ) {
        getData("url.php", id, v)
            .done(function() {
                $('#wrapper').show();
                $('button[data-year="'+v+'"]').addClass('active');
                someorefunctions();
            })
    });

问题是,当getData有实际的数据响应时,我似乎不知道如何突破每个循环。如果有2014年的数据,我希望循环到2014年,因为它会返回2014年的信息,所以按照指示显示数据,然后停止发送所有剩余年份的请求。

我听到过关于强制同步的一般警告,因为ajax具有异步特性,所以没有将其放入循环中。但我也想防止加载大量不需要的数据。

这可能吗?我最初使用async: false编写了所有这些代码,但我真的想放弃它。

编辑:睡了一夜之后,我觉得我想做的是不可能的。因为是否发出下一个ajax请求取决于前一个请求是否成功/返回数据,所以我必须同步处理。.each发送请求,但它将继续发送下一个请求,而不管上一个请求是否已经完成。我的痛点是,虽然我希望这个特定的循环ajax同步运行,但这并不意味着我希望所有其他脚本都停止。

EDIT我最终使用了一个版本的ajax调用本身,这确实解决了在第一个成功的数据响应时停止ajax的主要问题。

function getFirstData(path,id,years,idx) {
        return $.ajax({
            url: "includes/"+path,
            data: { id: id, year: years[idx] },
            dataType:"json",
            success: function(data) {
                successfunctions();
            },
            error: function(xhr) {
                getFirstData(path,id,years,++idx);
            }
        });
    }
getFirstData("getDonorsByCycle.php", id , [2016,2015,2014,2013] , 0);

您是否考虑过使用一个ajax调用一次性检索所有年份的数据,然后相应地处理数据
如果不可能,您可以维护当前正在处理的年份,然后只有在没有返回数据的情况下,才让getData在下一年调用自己。如果返回了数据,请处理回调并退出getData调用。以下内容应该有效。

var years = [2015, 2014, 2013, 2012, 2011];
function getData(path,id,idx) {
    return $.ajax({
        url: "includes/"+path,
        data: { id: id, year: years[idx] },
        dataType:"json",
        success: function(dataFromServer) {
            if (dataFromServer)
                $('#wrapper').show();
                $('button[data-year="'+years[idx]+'"]').addClass('active');
                someorefunctions();
            else
                getData(path,id,++idx);
        },
        error: function(xhr) {
            handleError(xhr);
    });
}
getData("url.php", id, 0);

我没有完全理解这个问题,但希望这能有所帮助。

使用success而不是done。success函数仅在返回某些数据时执行。因此,如果您有实际的数据响应,success函数就会启动。

success中,您可以return false;退出循环。

$.each([ 2015,2014,2013,2012,2011 ], function( k, v ) {
        getData("url.php", id, v)
            .success(function() {
                //do something
                if(breakcondition)
                {
                  return false;
                 }
            })
    });

您可以以类似的方式使用error来处理不返回数据的情况。