Jquery 延迟 & 每个循环
Jquery Defer & Each Loop
我对 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,但目前它 returns 0。我不确定我到底在哪里出错了。
首先,不要使用 $.each
和推送,因为你有一个从源数组到目标数组的 1:1 映射,你应该使用 Array.prototype.map
.
其次,由于 $.getJSON
已经 returns 一个 $.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 调用返回的数据和 returns 解析为名称数组、统计数据和嵌套能力数组的承诺。
尽管如此,我可能会将其分为两个函数 - 一个处理单个 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));
我对 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,但目前它 returns 0。我不确定我到底在哪里出错了。
首先,不要使用 $.each
和推送,因为你有一个从源数组到目标数组的 1:1 映射,你应该使用 Array.prototype.map
.
其次,由于 $.getJSON
已经 returns 一个 $.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 调用返回的数据和 returns 解析为名称数组、统计数据和嵌套能力数组的承诺。
尽管如此,我可能会将其分为两个函数 - 一个处理单个 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));