【问题标题】:How to recursively fetch data from paginated API then combine into one array如何递归地从分页 API 中获取数据,然后组合成一个数组
【发布时间】:2022-10-05 11:13:04
【问题描述】:

下面我尝试编写一个条件来获取分页 api,然后将其映射到另一个正在获取的 api。即将出现的一个问题是它在拉出一个分页页面或一个下一页后不会继续循环。第二个问题是从页面中获取的数据没有组合到一个数组中。我做错了什么或错过了什么?

const fetchURL = `${baseURL}?owner=${accounts[0]}`;
  fetch(fetchURL, {
   method: 'GET',
   redirect: 'follow',
  })
    .then(resp => resp.json())
    .then(data => {
      console.log(data);
      const pageKey = data.pageKey
      if (pageKey !== 0) {
        fetch(`${baseURL}?owner=${accounts[0]}&pageKey=${pageKey}`, {
            method: 'GET',
            redirect: 'follow',
            })
              .then(resp => resp.json())
              .then(data => {
                console.log(data)
              })
           return data.ownedNfts.concat(data.ownedNfts)
      } else {
           return data
      }

   const responses = data.ownedNfts.map((ownedNfts) =>
       fetch(`${baseURL1}stats?address=${ownedNfts.contract.address}`)
        .then((res) => res.json()),
   );

【问题讨论】:

    标签: javascript arrays pagination fetch-api


    【解决方案1】:

    要从 api 管理分页,您可以尝试这样的递归。

    你应该有一个带有增量参数的请求循环的脚本,以及一个打破循环的阈值。您必须通过时间睡眠或类似的方式来管理来自您的 api 的请求延迟。

    下面的示例在带有 axios 的节点环境中工作,您可以尝试它并使其适应您的环境。

    const { default: axios } = require('axios');
    
    // Init a bigData array to push new data on each iteration
    const bigData = [];
    
    async function fetchAllPaginateData(
        pageKey = 0 /** init by default page index 0 */,
    ) {
        try {
            const fetchURL = `https://api.instantwebtools.net/v1/passenger?page=${pageKey}&size=1`;
            const response = await axios.get(fetchURL);
            const { data } = response;
            const { totalPages } = data; // Your api should give you a total page count, result or something to setup your iteration
    
            bigData.push(data); // push on big data response data
    
            // if current page isn't the last, call the fetch feature again, with page + 1
            if (
                pageKey < totalPages &&
                pageKey < 10 // (this is a test dev condition to limit for 10 result) */
            ) {
                pageKey++;
                await new Promise((resolve) => setTimeout(resolve, 200)); // setup a sleep depend your api request/second requirement.
                console.debug(pageKey, '/', totalPages);
                return await fetchAllPaginateData(pageKey);
            }
    
            console.clear();
            return console.info('Data complete.');
        } catch (err) {
            console.error(err);
        }
    }
    
    fetchAllPaginateData().then(() => console.table(bigData));
    

    【讨论】:

      【解决方案2】:

      我稍微修改了前面的答案,使其包含在一种方法中,而不是在更大范围内修改有效负载。

      const axios = require('axios');
      
      (async (API_URL, LIMIT = 10) => {
          const fetchData = async (accountId, reqSize, currentPage) => {
              const fetchURL = `${API_URL}?owner=${accountId}&size=${reqSize}&page=${currentPage}`;
              return await axios.get(fetchURL);
          }
      
          const fetchAllPaginateData = async (accountID, reqSize = 20, currentPage = 0, combineData = []) => {
              try {
                  const { totalPages, totalPassengers, data } = await fetchData(accountID, reqSize, currentPage);
      
                  console.debug(`${totalPassengers} Passengers`, '/', `Needing ${totalPages} pages`, '/', `${reqSize} passengers per page`);
      
                  combineData = combineData.concat(data);
      
                  if (currentPage < totalPages && currentPage < LIMIT) {
                      currentPage++;
                      console.debug(currentPage, 'of', totalPages, 'pages');
      
                      // Slow down requests so as not to DOS the API
                      await new Promise((resolve) => setTimeout(resolve, 200));
      
                      return await fetchData(reqSize, currentPage, combineData);
                  }
      
                  return combineData;
              } catch (err) {
                  console.error(err);
              }
          }
      
          fetchAllPaginateData(1007).then(data => console.table(data));
      })('https://api.instantwebtools.net/v1/passenger', 2);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-28
        • 1970-01-01
        • 1970-01-01
        • 2017-10-13
        • 2017-10-11
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        相关资源
        最近更新 更多