【问题标题】:How to parse JSON results properly如何正确解析 JSON 结果
【发布时间】:2022-11-21 05:09:27
【问题描述】:
我目前正在使用PokeAPI,我正在执行获取请求以在给定端点接收回 JSON,然后尝试解析并返回它。可以在这里找到执行此操作的功能:
function getPokemon(id){
pokemonData = {
name:"",
image:"",
id:id,
description:""
}
// Documentation https://pokeapi.co/docs/v2#pokemon-species
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()
}
)
// Documentation: https://pokeapi.co/docs/v2#pokemon
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"] 并且似乎没有什么不同。任何帮助,将不胜感激
【问题讨论】:
标签:
javascript
fetch
fetch-api
【解决方案1】:
在写这篇文章的过程中,我弄清楚发生了什么。当使用 .then() 时,我的理解是这也在等待响应并使其同步,因为在线资源说明了这一点。
这不是真的.
我必须让我的函数成为一个异步函数,这样我才能等待获取,因为该函数的运行速度比获取可能发生的速度快。固定代码是:
async function getPokemon(id){
pokemonData = {
name:"",
image:"",
id:id,
description:""
}
// Documentation https://pokeapi.co/docs/v2#pokemon-species
await 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()
}
)
// Documentation: https://pokeapi.co/docs/v2#pokemon
await fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)
.then((response) => response.json())
.then((data) => {
pokemonData.image = data.sprites.other["official-artwork"].front_default
pokemonData.name = data.name
console.log(data.name)
}
)
return pokemonData
}
【解决方案2】:
您自己的答案在解决您的问题方面是正确的。
但它并没有充分利用async / await 和承诺。
在 fetch 调用上使用 await 使代码一个接一个地运行请求。您可以通过同时运行 fetch 调用来加快速度在平行下并等待两者都以 Promise.all() 结束。
在两个请求都完成后,创建您的 pokemonData 对象并根据两组数据返回它。
async function getPokemon(id) {
const speciesRequest = fetch(`https://pokeapi.co/api/v2/pokemon-species/${id}/`)
.then((response) => response.json())
const pokemonRequest fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)
.then((response) => response.json())
try {
const [speciesData, pokemonData] = await Promise.all([speciesRequest, pokemonRequest]);
return ({
id,
image: pokemonData.sprites.other["official-artwork"].front_default,
name: pokemonData.name,
description: speciesData.flavor_text_entries[0].flavor_text.toString()
});
catch (error) {
return Promise.reject(error);
}
}