json JavaScript,fetch,API

i2byvkas  于 2023-08-08  发布在  Java
关注(0)|答案(2)|浏览(109)

我想做以下事情:从这个网站https://swapi.dev/api/people/获取一个随机名称,我这样做了,我可以在我的html页面中看到它,然后我还想获得一个随机星球,在这里我需要访问homeworld密钥,并返回链接,在返回链接之前,我格式化为获得一个随机URL,从这个我也必须在我的页面上显示星球的名称。第一次抓取工作正常,至少我认为,但第三个.then()不工作,或者至少我不知道如何从homeworld URL访问信息。这是我第一次尝试fetch(),如果你能告诉我我在代码中哪里做错了,也许有不同的解决方案,但不是那么复杂,那就太好了。

let randomNumber = Math.floor(Math.random()*9)

const fetchPromise = fetch("https://swapi.dev/api/people/");

let test
let test2
let planets = document.querySelector('#age')
fetchPromise
    .then((response) => {
        if (!response.ok) {
            throw new Error(`Http error: ${response.status}`);

        }
        return response.json();
    })
    .then((json) => {
        console.log(json.results[randomNumber].name)
        showRandomUserData(json)
        test = json.results[0].homeworld
        test = test.slice(0, -2)
        // console.log(test + randomNumber + "/");
        // console.log(test + "/" + randomNumber + "/");
        test = test + randomNumber + "/";
        return fetch(test)
        // return fetch("https://swapi.dev/api/planets/2/");
    })
    .then(response => response.json()).then(json =>
    {   test2=json.name
        console.log(test2);
        planets.innerHTML = test2
    }) 

showRandomUserData = (randomUser) => {
    document.querySelector("#name").innerHTML =
        randomUser.results[randomNumber].name;

}

字符串
已解决

nafvub8i

nafvub8i1#

这里有一个简单的解决方案,使用fetch()从这两个URL中获取数据,然后将返回的所有人和一个星球插入到您的网页中:

function myFetch(...args) {
    return fetch(...args).then(response => {
        if (!response.ok) {
            throw new Error(`fetch failed with status ${response.status}`);
        }
        return response.json();
    });
}

Promise.all([
    myFetch("https://swapi.dev/api/people/"),
    myFetch("https://swapi.dev/api/planets/2/")
]).then(([people, planet]) => {
    const peopleDiv = document.getElementById("people");
    let peopleHTML = "";
    for (let p of people.results) {
        peopleHTML += `<div>${p.name}</div>`;
    }
    peopleDiv.innerHTML = peopleHTML;
    
    const planetDiv = document.getElementById("planets");
    let planetHTML = `<div>${planet.name}</div>`;
    planetDiv.innerHTML = planetHTML;
}).catch(err => {
    console.log(err);
});

个字符
至于使用结果,people URL返回如下结构:

{
  count: 82,
  next: 'https://swapi.dev/api/people/?page=2',
  previous: null,
  results: [
    {
      name: 'Luke Skywalker',
      height: '172',
      mass: '77',
      hair_color: 'blond',
      skin_color: 'fair',
      eye_color: 'blue',
      birth_year: '19BBY',
      gender: 'male',
      homeworld: 'https://swapi.dev/api/planets/1/',
      films: [Array],
      species: [],
      vehicles: [Array],
      starships: [Array],
      created: '2014-12-09T13:50:51.644000Z',
      edited: '2014-12-20T21:17:56.891000Z',
      url: 'https://swapi.dev/api/people/1/'
    },
    {
      name: 'C-3PO',
      height: '167',
      mass: '75',
      hair_color: 'n/a',
      skin_color: 'gold',
      eye_color: 'yellow',
      birth_year: '112BBY',
      gender: 'n/a',
      homeworld: 'https://swapi.dev/api/planets/1/',
      films: [Array],
      species: [Array],
      vehicles: [],
      starships: [],
      created: '2014-12-10T15:10:51.357000Z',
      edited: '2014-12-20T21:17:50.309000Z',
      url: 'https://swapi.dev/api/people/2/'
    }
}


所以,你有people.results,这是一个数组,你可以访问people.results[n],从这个数组中获取一个元素。该项目将是一个具有.name.height等属性的对象。
您显示的特定planet URL返回一个类似于以下的planet对象:

{
  name: 'Alderaan',
  rotation_period: '24',
  orbital_period: '364',
  diameter: '12500',
  climate: 'temperate',
  gravity: '1 standard',
  terrain: 'grasslands, mountains',
  surface_water: '40',
  population: '2000000000',
  residents: [
    'https://swapi.dev/api/people/5/',
    'https://swapi.dev/api/people/68/',
    'https://swapi.dev/api/people/81/'
  ],
  films: [
    'https://swapi.dev/api/films/1/',
    'https://swapi.dev/api/films/6/'
  ],
  created: '2014-12-10T11:35:48.479000Z',
  edited: '2014-12-20T20:58:18.420000Z',
  url: 'https://swapi.dev/api/planets/2/'
}


因此,您可以像在planet.name中那样访问该对象的属性。
请注意,人员结果是分页的。总共有82个结果,但只有10个出现在第一个结果中。其余的则是其他页面的结果,如https://swapi.dev/api/people/?page=2

56lgkhnf

56lgkhnf2#

类似于this answer,但使用async/await来避免回调地狱。如果可以的话,尝试使用这种方法。Why?
jfriend00的回答中,推荐使用Promise.all而不是单独的fetch调用,因为这样可以并行地进行fetch。To know more的函数。
sandbox测试和尝试

const fetchData = async (...args) => {
  try {
    const response = await fetch(...args);
    return response.json();
  } catch (err) {
    throw new Error(`fetch failed with status ${err?.message}`);
  }
};

const updateDOM = (people, planet) => {
  document.getElementById("people").innerHTML = 
   people.results.reduce((s, p) => s + `<div>${p.name}</div>`, "");
  document.getElementById("planets").innerHTML = `<div>${planet.name}</div>`;
};

const populateData = async () => {
  try {
    const [people, planet] = await Promise.all([
      fetchData("https://swapi.dev/api/people/"),
      fetchData("https://swapi.dev/api/planets/2/"),
    ]);

    // do stuff with 'people' or 'planet'
    // example, get
    // const firstPersonsHomeworld = people.results[0].homeworld;
    // console.log(firstPersonsHomeworld);
    // or
    // const planetName = planet.name;
    // console.log(planetName);

    updateDOM(people, planet);
  } catch (err) {
    // errorHandler(err);
    console.error(err);
  }
};

// start app
populateData();

字符串

相关问题