【问题标题】:Jquery getJSON inside getJSON synchronousjquery getJSON里面getJSON同步
【发布时间】:2023-03-10 18:03:01
【问题描述】:

我有以下代码通过 $.getJSON 连接到 API,获取 JSON,然后通过 for 循环循环 3 次(因为它有 3 个对象为 data.length)。在这 3 次迭代中的每一次迭代中,它都会创建另一个 $.getJSON,以从第一个连接的迭代中获取具有所需参数的特定新数据。

    var baseAPI = "https://api.guildwars2.com/";
    var versionAPI = ["v1", "v2"];
    var endpointAPI = ["account", "guild_details.json", "guild", "stash", "items"];
    var bearerAPI = ["access_token", "guild_id"];

    $('#keyInput_user_FORM').on('submit', function(e) {
        e.preventDefault();
        var mordant = "https://api.guildwars2.com/v2/guild/927CDDD7-4E8D-E411-A8E7-AC162DAE5A05/stash?access_token=EDCD27E4-3A1B-3C44-9C5B-99F062596A9BB1C9C824-AE01-4F6F-9EA9-CBAD2D721C9D";
        $(".JuilsContainer").append('<div class="bankResult"></div>');

        $.getJSON( encodeURI(mordant), {
            tagmode: "any",
            format: "json"
        }).done(function( data ) {
            for(var bankCount = 0; bankCount < data.length; bankCount++){
                $(".bankResult").append('<div class="inventory" id="upgradeID_'+data[bankCount].upgrade_id+'"><header>'+data[bankCount].note+'</header><ul class="inventory_UL"></ul></div>');
                $.each( data[bankCount].inventory, function( i, inventory ){ /*can also run on property .size but running inventory guarantees not running more or less than there are items instead of slots.*/
                    if(data[bankCount].inventory[i] != null){
                        var accountAPI = baseAPI + versionAPI[1] + "/" + endpointAPI[4] + "/" + data[bankCount].inventory[i].id;
                        $.getJSON( encodeURI(accountAPI), {
                            tagmode: "any",
                            //async: false,
                            format: "json"
                        }).done(function( item_data ) {
                            $('#upgradeID_'+ data[bankCount].upgrade_id + ' .inventory_UL').append('<li class="bankInventory_item" id="item_'+item_data.id+'"><img src="'+encodeURI(item_data.icon)+'"><span class="itemCount">'+ data[0].inventory[i].count + '</span></li>');
                        });
                    }else{
                        $('#upgradeID_'+ data[bankCount].upgrade_id + ' .inventory_UL').append('<li class="bankInventory_item" class="item_null"></li>');   
                    }
                });
            }
        });

    });

遗憾的是,第一个循环中的所有$.getJSON 调用都在 3 次迭代完成后完成,循环结束。我希望第二个连接在循环内生效,而不是在循环 3 次后生效。

此外,由于某种原因,当它到达所有第二个 $.getJSON 调用时,它没有使用正确的迭代 var。变量bankCount 似乎是3,而它只能达到2,因为它有3 个对象进行计数和循环。

这发生在这条线上。

$('#upgradeID_'+ data[bankCount].upgrade_id + ' .inventory_UL').append('<li class="bankInventory_item" id="item_'+item_data.id+'"><img src="'+encodeURI(item_data.icon)+'"><span class="itemCount">'+ data[0].inventory[i].count + '</span></li>');

当它尝试使用 data[bankCount].upgrade_idbankCount 似乎是 3 而只有 3 个对象时(因此它应该最大为 2,因为不再有。)

所有$.getJSON 调用都不会立即执行。它们以某种方式排队,直到所有循环完成。只有当它从第一个 $.getJSON 循环完成 3 次时,它才会执行并从循环内排队的那些中返回所有内容。 ^ 问题已编辑,希望更清楚

当只有 3 个对象时,变量 bankCount 如何变成 3(因此应该是最大 2)。

【问题讨论】:

  • 你同时问了两个问题,但至于bankCount的问题,见stackoverflow.com/questions/750486/…。第二个问题我完全不明白。
  • "当只有 3 个对象时,变量 bankCount 怎么变成 3(因此应该是最大 2)。"因为 2+1 等于 3,当为 3 时,for 循环停止。
  • @Juhana 我已经编辑了关于其他问题的帖子
  • 留下一个被否决的理由会很好..

标签: javascript jquery json loops getjson


【解决方案1】:

旁白:我不确定为什么当您将 async 设置为 false 时代码没有执行您想要的操作。但是,我说,这并不是一个真正有趣的案例,因为你真的不想进行同步 ajax 调用——它只会导致网页无响应并且用户体验通常很差。

所以,我要把你的问题翻译成: “我想遍历一组对象;在每个对象上异步调用 $.getJSON;并且仅在前一个调用完成后才开始每个调用。”

您可以通过在上一次调用的 .done 处理程序中对 $.getJSON 进行每次调用来做到这一点。

如果您的数据中始终只有三个元素,那么您可以通过将三个调用嵌套到 $.getJSON 以简单(但丑陋)的方式做到这一点。

但是,我假设您的数据可以是任意长度。这迫使您使用更清洁的解决方案...

您需要用递归调用替换您的 for 循环迭代。

类似于以下内容:

...
submitHelper(data, 0);
...

function submitHelper(data, pos) {
  if (pos >= data.length) {
    return;
  }
  $.getJSON(..., done: function(itemData) {
    ...
    submitHelper(data, pos++);
    }
...

【讨论】:

  • 我遇到的异步问题是,它按照完成 ajax 调用的顺序创建元素。不按提供数据的顺序。
  • @KrijnvanderBurg 此答案中的解决方案导致它们在提供的订单数据中被接收。缺点是它一次只发出 1 个请求,所以会比较慢。
  • 我真的迷路了。我不知道如何将上述代码实际应用于我的。我们说话时正在努力
  • 抱歉,先生们,但我不知道如何应用上面的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-21
  • 2020-05-20
  • 2011-05-07
  • 2010-12-09
  • 2013-08-10
  • 2013-05-26
  • 1970-01-01
相关资源
最近更新 更多