我对JSON和Deferrers有点新鲜,所以道歉答案显而易见。
我正在使用pokeapi.co,我正在尝试使用getJSON提取各种口袋妖怪的细节。我创建了一个函数,它接受一个URL数组,运行getJSON函数从URL中提取数据,迭代数据并将其推送到数组中。我试图使用延迟对象并承诺确定何时完成所有操作,以便我可以在另一个函数中使用数据。不幸的是,我似乎做错了什么。
var url = [
"http://pokeapi.co/api/v2/pokemon/1/",
"http://pokeapi.co/api/v2/pokemon/2/"
];
function getPokemonDetails(url){
var def = $.Deferred();
var promises = [];
var pokemon;
$.each(url, function(i, index){
var deferred = $.Deferred();
$.getJSON(index, function(data){
pokemon = [data.name, data.stats];
var abilityURLs = [];
$.each(data.abilities, function(a, abilities){
abilityURLs.push(abilities.ability.url)
});
pokemon.push(abilityURLs);
deferred.resolve(pokemon);
}); //End getJSON
deferred.done(function(data){
promises.push(data);
console.log(promises);
})// End Deferred
}); //End Each
$.when(...promises).done(function(){
console.log(arguments.length);
});
}
getPokemonDetails(url);
目前,当console.log运行时,我希望promises数组的长度为2,但此刻它返回0.我不确定我到底出错了。
答案 0 :(得分:1)
首先,不要使用$.each
和推送,因为从源数组到目标数组的映射是1:1,所以应该使用Array.prototype.map
。
其次,由于$.getJSON
已经返回$.Deferred()
,因此绝对不需要创建自己的一个。
因此,如果我正确地遵循您当前的代码,可以完全替换它:
function getPokemonDetails(url_list) {
return $.when(... url_list.map(url =>
$.getJSON(url).then(
data => [ data.name, data.stats, [
data.abilities.map(ability => ability.ability.url)
]]
)
));
}
内部.then
调用获取从每个AJAX调用返回的数据,并返回一个promise,该promise将解析为name,stats和嵌套数组的数据。
对于它的价值,我可能会把它分成两个函数 - 一个处理单个URL,另一个可以处理多个函数:
const getPokemonDetails = url => $.getJSON(url).then(
data => [ data.name, data.stats, [
data.abilities.map(ability => ability.ability.url)
]]);
const getMultiPokemonDetails = list => $.when(...list.map(getPokemonDetails));