【问题标题】:How to loop through Ajax Requests inside a JQuery When - Then statment?如何在 JQuery When - Then 语句中循环 Ajax 请求?
【发布时间】:2013-08-25 01:08:48
【问题描述】:

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

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

在我尝试过的代码上。

 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);
    });

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

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

是否有人对我如何发出一堆 Ajax 请求并等到它们都完成后再触发事件有任何建议?或者去修复我目前拥有的东西?

提前感谢您的帮助。

【问题讨论】:

标签: javascript jquery ajax


【解决方案1】:

可以按照您的要求进行操作。但是,您向其发送请求的服务器可能有其实施限制的原因。作为从事 Web 开发工作的人,并且亲眼目睹了 DDOS、抓取和其他 API 滥用是多么令人讨厌,我建议遵守它们的限制。

话虽如此,这就是你可以做到的。

$.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
});

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

编辑:我忘了添加 5s 的分割,但这说明了一般的想法。您可能可以从这里弄清楚如何将其应用于您的问题。顺便说一句,您可以使用 array.splice(0,5) 从数组中获取接下来的 5 个结果。 .splice 使用安全;如果元素总数小于5,则只取剩余的所有元素。

【讨论】:

  • 竖起大拇指,这完全符合我的需要。很好的答案和很好的解释。谢谢你的时间。是的,我会研究一种不同的方式来访问我需要的数据,因为你有这个限制是有原因的。
  • 很好的解释!像魅力一样工作。
  • 如果我错过了,我很抱歉,但是您如何捕捉和评估回复
  • then 函数参数将包括集体响应。
  • always() 对于第一个 ajax 帖子只调用一次。当循环中的所有调用都完成时,我如何捕捉到,无论成功与否?
【解决方案2】:

您可以使用Async.js libray。并尝试each 函数。

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    相关资源
    最近更新 更多