我有以下代码通过$.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_id
时,bankCount
似乎是3,而只有3个对象(因此它最多应为2,因为不再有。)
所有$.getJSON
次来电都不会马上执行。它们以某种方式排队,直到完成所有循环。只有当它完成从第一个$.getJSON
循环完成3次后才执行,并从循环内排队的那些返回全部。
^编辑问题,希望更清晰
当只有3个对象时,变量bankCount
如何变为3(因此应该是最大值2)。
答案 0 :(得分:0)
侧点:当你将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++);
}
...