【问题标题】:How do you fetch multiple pages of data into an array?如何将多页数据提取到数组中?
【发布时间】:2021-11-08 20:31:36
【问题描述】:

这是我的代码

let url;
let planetCount;
let planetData = [];

//turn through the pages
for (let p = 1; p < 7; p++) {
  url = `https://swapi.boom.dev/api/planets?page=${p}`;

  //fetch data
  for (let j = 0; j < 1; j++) {
    fetch(url).then(res => res.json())
      .then(data => {

        //push data to array
        for (let i = 0; i < data.results.length; i++) {
          planetData.push(data.results[i]);
        }
      })

    console.log(planetData)

  }
}

这是输出: https://i.stack.imgur.com/Hivwr.png

问题:我怎样才能让它全部进入一个数组,而不是 6 个?

【问题讨论】:

  • 您的 console.log 仍处于 for 循环中,因此您显示 6 次相同的数组,但每次该数组为空
  • 您的第一个 for 循环中有一个 console.log,它运行了 6 次。我认为代码看起来是正确的:)

标签: javascript arrays for-loop fetch


【解决方案1】:

您确实只有一个数组。因为您在循环中运行console.log(),所以您只得到了六次输出。

我用正确的方式扩展了您的代码以处理多个异步调用并等待它们全部完成:

let url;
let planetCount;
let planetData = []
let promises = [];

//turn through the pages
for (let p = 1; p < 7; p++) {
url = `https://swapi.boom.dev/api/planets?page=${p}`;

//fetch data
for (let j = 0; j < 1; j++) {
    promises.push(fetch(url).then(res => res.json())
        .then(data => {

            //push data to array
            for (let i = 0; i < data.results.length; i++) {
                planetData = planetData.concat(data.results[i]);
            }

        }));
    }
}

Promise.all(promises)
.then(() => {
    console.log(planetData.length, '=>', planetData);
})

【讨论】:

    【解决方案2】:

    您可以使用async/awaitPromise.all() 来返回返回页面的数组。一旦有了这个,我们就可以使用Array.flat() 创建一个连续的行星数据数组:

    async function getPlanets() {
        const urls = Array.from( { length: 7 }, (v,i) => `https://swapi.boom.dev/api/planets?page=${i + 1}` );
        const promises = urls.map(url => fetch(url).then(res => res.json()).then(data => data.results));
        const planetData = (await Promise.all(promises)).flat();
        console.log(`Results for ${planetData.length} planets downloaded...`);
        console.log('Results:', planetData);
    }
    
    getPlanets()

    【讨论】:

    • 这太美了!我试图尽可能接近原始代码,以免增加额外的阅读复杂性。
    【解决方案3】:

    这是否回答了您的问题? How can I fetch an array of URLs with Promise.all?

    Promise all 应该是您使用的正确工具,这样您就可以等到所有 Promise 都解决后再处理响应

    【讨论】:

      【解决方案4】:

      问题与异步代码的工作方式有关。

      fetch() 函数最终会返回一个结果,但在您尝试记录它时该结果不可用。

      您必须等待检索结果。使用Aysnc/Await 来实现:

      async function turnThroughThePges() {
        let url;
        let planetCount;
        let planetData = [];
      
      
        //turn through the pages
        for (let p = 1; p < 7; p++) {
          url = `https://swapi.boom.dev/api/planets?page=${p}`;
          //fetch data
          for (let j = 0; j < 1; j++) {
            await fetch(url).then(res => res.json())
              .then(data => {
                for (let i = 0; i < data.results.length; i++) {
                  planetData.push(data.results[i]);
                }
              })
          }
        }
        return planetData;
      }
      
      turnThroughThePges().then(console.log);

      【讨论】:

        【解决方案5】:

        let url;
        let promises = [];
        
        //turn through the pages
        for (let p = 1; p < 7; p++) {
          url = `https://swapi.boom.dev/api/planets?page=${p}`;
        
          //fetch data
          promises.push(
            fetch(url)
              .then((res) => res.json())
              .then((data) => data.results)
          );
        }
        
        function handleRejection(p) {
          return p.catch((err) => ({ error: err }));
        }
        async function requests() {
          return await Promise.all(promises.map(handleRejection));
        }
        requests().then((planetData) => console.log(planetData.flat()));

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-28
          • 2020-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-11
          • 1970-01-01
          • 2020-05-17
          相关资源
          最近更新 更多