如何正确解析JSON结果?使用PokeAPI时异步请求属性访问为空
问题:PokeAPI异步请求导致返回数据异常
我正在使用PokeAPI,通过fetch请求指定端点获取JSON数据并解析,实现功能的函数如下:
function getPokemon(id){ pokemonData = { name:"", image:"", id:id, description:"" } // 获取宝可梦物种信息 fetch(`https://pokeapi.co/api/v2/pokemon-species/${id}/`) .then((response) => response.json()) .then((data) => { pokemonData.description = data.flavor_text_entries[0].flavor_text.toString() } ) // 获取宝可梦基础信息 fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`) .then((response) => response.json()) .then((data) => { pokemonData["image"] = data.sprites.other["official-artwork"].front_default.toString() pokemonData["name"] = data.name.toString() } ) return pokemonData }
调用该函数返回数据后,访问对象属性时显示为空,但查看对象本身却能看到正确信息(如下图所示):
我尝试了不同的属性访问方式(如data.name和data["name"]),但均无效果,希望得到相关帮助。
问题原因
fetch是异步操作,函数执行时会立刻返回初始的pokemonData对象,此时两个fetch请求还未完成,属性还没被赋值;等后续请求完成后,对象的属性才会被更新,所以你直接查看对象时能看到最新值,但提前访问时拿到的是初始空值。
解决办法
将函数改为异步函数,使用async/await处理请求,确保所有数据获取完成后再返回结果,同时用Promise.all并行发起两个请求提升效率:
async function getPokemon(id){ const pokemonData = { name:"", image:"", id:id, description:"" } // 并行发起两个接口请求 const [speciesResponse, pokemonResponse] = await Promise.all([ fetch(`https://pokeapi.co/api/v2/pokemon-species/${id}/`), fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`) ]); // 解析返回的JSON数据 const speciesData = await speciesResponse.json(); const pokemonRawData = await pokemonResponse.json(); // 赋值到目标对象 pokemonData.description = speciesData.flavor_text_entries[0].flavor_text; pokemonData.image = pokemonRawData.sprites.other["official-artwork"].front_default; pokemonData.name = pokemonRawData.name; return pokemonData; }
调用方式
由于函数是async函数,调用时需要通过await(在异步函数内)或.then()获取结果:
// 方式1:使用.then() getPokemon(1).then(pokemon => { console.log(pokemon.name); // 正常获取属性值 }); // 方式2:在async函数内使用await async function showPokemon() { const pokemon = await getPokemon(1); console.log(pokemon.image); } showPokemon();
内容的提问来源于stack exchange,提问作者Kieran Wood
相关产品推荐
相关产品推荐

