如何在多个页面上获取数据?

时间:2016-11-18 12:58:49

标签: javascript reactjs redux fetch redux-saga

我的项目基于React,redux,redux-saga,es6,我尝试从此API获取数据:

http://api.dhsprogram.com/rest/dhs/data/BD,2000,2004,2007?&returnFields=CharacteristicLabel,Indicator,IndicatorId,Value&f=json

正如您所看到的,此特定API调用显示的数据在40页上显示每页限制为100个数据。

根据这个答案: http://userforum.dhsprogram.com/index.php?t=msg&th=2086&goto=9591&S=Google 它表示你可以将限制扩展到每页最多3000data。

但是,在某些情况下,我会进行超出该限制的API调用,这意味着我不会像以下那样接收所有数据:

export function fetchMetaData(countryCode: string, surveyYears: string) {
return (fetch('http://api.dhsprogram.com/rest/dhs/data/' + countryCode + ',' + surveyYears + '?returnFields=CharacteristicLabel,Indicator,IndicatorId,Value&f=json')
    .then(response => response.json())
    .then(json => json.Data.map(survey => survey)))
} 

所以我的问题是;鉴于我知道数据的总页数,从这个API获取所有数据的最佳方法是什么。论坛链接中的答案建议循环使用API​​。但是,我无法找到正确的语法用法来执行此操作。

我的想法是进行一次api调用以获取总页数。然后使用redux + redux-saga将其存储在一个状态中。然后执行一个新请求,将总页数作为参数发送,并获取此总页数。通过这样做,我无法弄清楚每次迭代存储数据的语法。

2 个答案:

答案 0 :(得分:4)

一种可能的解决方案 - 想法是首先获取页数,然后进行适当数量的API调用,将每次调用的承诺推送到数组中。然后我们等待所有承诺解决,并对返回的数据做一些事情。

function fetchMetaData() {
    let pagesRequired = 0;

    fetch('apiUrlToGetPageNumber')
    .then(resp = > {
        const apiPromises = [];
        pagesRequired = resp.data.pagesRequired;

        for (let i=pagesRequired; i>0;i--) {
            apiPromises.push(fetch('apiUrlToSpecificPage?page = ' + i));
        }

        Promise.all(apiPromises)
        .then(responses => {
            const processedResponses = [];
            responses.map(response => {
                processedResponses.push(response);
            }

            // do something with processedResponses here
        });
    }
}

答案 1 :(得分:0)

这是使用async/await的另一种可能的解决方案。这样做的好处是total_pages计数是动态的,所以如果它在处理您的请求时增加,那么它将确保您完成所有操作。

async function fetchMetaData() {
  let allData = [];
  let morePagesAvailable = true;
  let currentPage = 0;

  while(morePagesAvailable) {
    currentPage++;
    const response = await fetch(`http://api.dhsprogram.com/rest/dhs/data?page=${currentPage}`)
    let { data, total_pages } = await response.json();
    data.forEach(e => allData.unshift(e));
    morePagesAvailable = currentPage < total_pages;
  }

  return allData;
}