javascript 如何在 JQuery When - Then 语句中循环遍历 Ajax 请求?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18424712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 11:52:30  来源:igfitidea点击:

How to loop through Ajax Requests inside a JQuery When - Then statment?

javascriptjqueryajax

提问by recneps

I am trying to load a bunch of data from an API Async and when all the data is loaded I want to trigger an event that all the data is loaded. The problem I am having is that the API I am using limits the number of response objects to five. And I would potentially need to retrieve 30-40 response objects.

我正在尝试从 API Async 加载一堆数据,当所有数据都加载完毕后,我想触发一个加载所有数据的事件。我遇到的问题是我使用的 API 将响应对象的数量限制为五个。我可能需要检索 30-40 个响应对象。

So what I want to do is create a when - then statement that loops trough the data items and makes request for every five items then when all the items are loaded I want to fire a loaded event. The issue I am having is that the when-then statement is completing before the success of the ajax request.

所以我想要做的是创建一个 when - then 语句,它循环遍历数据项并对每五个项目发出请求,然后当所有项目都加载时,我想触发一个加载的事件。我遇到的问题是 when-then 语句在 ajax 请求成功之前完成。

onto the code I have tried.

到我试过的代码上。

 function loadsLotsOfStats(stats, dataType, eventName, dataName, callback) {
     var groupedStats = [];
     while (stats.length > 0) {
         groupedStats.push(stats.splice(0, 5).join('/'));
     }
    j$.when(
        groupedStats.forEach(function (d) {
            loadJSONToData(model.apiUrl.replace("{IDS}", d), "json", "", dataName, function (d) { /*console.log(d);*/ }, true)
        })
    ).then(function () {
        j$(eventSource).trigger('dataLoaded', eventName);
    });

The loadJSONToData function is basically just a wrapper function for an Async $.ajax.

loadJSONToData 函数基本上只是一个 Async $.ajax 的包装函数。

so yeah the event is getting triggered before the data is actually loaded. Also for some reason if I try to put for loop right in the when( statement it through a syntax error?

所以是的,事件在实际加载数据之前被触发。同样出于某种原因,如果我尝试将 for 循环放在 when( 通过语法错误声明它?

Does anyone have any advice on how I could make a bunch of Ajax requests and wait until they all are compeleted before triggering an event? Or a away to fix what I currently have?

有没有人对我如何发出一堆 Ajax 请求并等到它们全部完成后再触发事件有什么建议?或者去修理我目前拥有的东西?

Thanks in advance for the help.

在此先感谢您的帮助。

回答by tandrewnichols

It's possible to do what you're asking. HOWEVER, the server you are sending your requests to probably has a reason for the limit they enforce. As someone who works in web development and has seen first hand how annoying DDOS, scraping, and other abuses of APIs can be, I would suggest conforming to their limit.

有可能做你所要求的。但是,您向其发送请求的服务器可能有其强制执行限制的原因。作为一名从事 Web 开发工作并亲眼目睹 DDOS、抓取和其他 API 滥用有多烦人的人,我建议遵守他们的限制。

That being said, here's how you can do it.

话虽如此,这是您的方法。

$.ajax actually returns a deferred object, so you can use that to your advantage. Also $.when can accept any number of deferred objects. Combining these two facts can solve your problem.

$.ajax 实际上返回一个延迟对象,因此您可以利用它来发挥自己的优势。另外 $.when 可以接受任意数量的延迟对象。结合这两个事实可以解决您的问题。

var deferreds = [];
$.each(groupedStats, function(index, stat){
    deferreds.push(
        // No success handler - don't want to trigger the deferred object
        $.ajax({
            url: '/some/url',
            data: {stat: stat},
            type: 'POST'
        })
    );
});
// Can't pass a literal array, so use apply.
$.when.apply($, deferreds).then(function(){
    // Do your success stuff
}).fail(function(){
    // Probably want to catch failure
}).always(function(){
    // Or use always if you want to do the same thing
    // whether the call succeeds or fails
});

Note that this is not a race condition. Although $.ajax is asynchronous, $.each is not, so your list of deferreds will be the total list before you get to $.when and $.then/$.fail/$.always will only be triggered once they all complete.

请注意,这不是竞争条件。尽管 $.ajax 是异步的,但 $.each 不是,因此您的延迟列表将是您到达 $.when 之前的总列表,而 $.then/$.fail/$.always 只会在它们全部完成后触发.

EDIT: I forgot to add the splitting by 5s, but this illustrates the general idea. You can probably figure out from here how to apply it to your problem. Incidentally, you could just use array.splice(0,5) to get the next 5 results from the array. .splice is safe to use; if the total number of elements is less than 5, it will just take all the remaining elements.

编辑:我忘记添加 5s 的拆分,但这说明了总体思路。您可能可以从这里找出如何将其应用于您的问题。顺便说一句,您可以使用 array.splice(0,5) 从数组中获取接下来的 5 个结果。.splice 使用安全;如果元素总数小于 5,它只会取所有剩余的元素。

回答by Jake Lin

You can use Async.js libray. and try the eachfunction.

您可以使用Async.js 库。并尝试每个功能。