首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用HackerNews API将请求分页到API。

使用HackerNews API将请求分页到API。
EN

Stack Overflow用户
提问于 2021-02-22 07:17:39
回答 1查看 160关注 0票数 0

*问题很简单,我只是写了很多具体的东西。***

我在网上找了几个小时,似乎找不到答案。大多数分页都是在收到来自API调用的数据之后进行的,或者是使用自己的服务器构建的后端node.js。

我的问题是,我有一个返回500个ID的数组的API请求,然后是第二个多API调用,循环通过每个ID进行promise API调用。我使用Promise.all方法。完成此请求需要2-3分钟。

目前,我做了一个快速过滤器来获得前十个结果,这样它就会显示出来,我可以渲染数据来处理其他事情,比如渲染组件和样式。

我的问题是,我希望能够在API调用仍在进行的同时对数据进行分页。

基本上,Promise.all连续发送10个id的数组(10个API调用),get。但是在第一组十个之后,我想开始接收要渲染的数据。

现在,我的filter方法只能得到10个。或者等待2-3分钟,直到全部500个渲染完成。

这是我的request.js文件(它是我的应用程序组件的一部分,为了清楚起见,我只是将它分开)。

代码语言:javascript
复制
    import axios from 'axios';
    import BottleNeck from 'bottleneck'

    const limiter = new BottleNeck({
      maxConcurrent: 1, 
      minTime: 333
    })


    export const Request = (setResults, searchBarType, setLoading) => {
      
      const searchBar = type => {
        const obj = {
          'new': 'newstories',
          'past': '',
          'comments': 'user',
          'ask': 'askstories',
          'show': 'showstories',
          'jobs': 'jobstories',
          'top': 'topstories',
          'best': 'beststories',
          'user': 'user'
        }
      
        return obj[type] ? obj[type] : obj['new'];
      }

      let type = searchBar(searchBarType)

      const getData = () => {
        const options = type
        const API_URL = `https://hacker-news.firebaseio.com/v0/${options}.json?print=pretty`;

        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }

      const getIdFromData = (dataId) => {
        const API_URL = `https://hacker-news.firebaseio.com/v0/item/${dataId}.json?print=pretty`;
        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }


      const runAsyncFunctions = async () => {
        setLoading(true)
        const {data} = await getData()
        let firstTen = data.filter((d,i) => i < 10);

        Promise.all(
          firstTen.map(async (d) => {
            const {data} = await limiter.schedule(() => getIdFromData(d))
            console.log(data)
            return data;
          })
          )
          .then((newresults) => setResults((results) => [...results, ...newresults]))
          setLoading(false)
        // make conditional: check if searchBar type has changed, then clear array of results first
      }  
      

      runAsyncFunctions()
    }

这是我的App.js文件

代码语言:javascript
复制
    import React, { useState, useEffect } from 'react';
    import './App.css';
    import { SearchBar } from './search-bar';
    import { Results } from './results';
    import { Request } from '../helper/request'
    import { Pagination } from './pagination';

    function App() {
      const [results, setResults] = useState([]);
      const [searchBarType, setsearchBarType] = useState('news');
      const [loading, setLoading] = useState(false);
      const [currentPage, setCurrentPage] = useState(1);
      const [resultsPerPage] = useState(3);
      

      // Select search bar button type 
      const handleClick = (e) => {
        const serachBarButtonId = e.target.id;
        console.log(serachBarButtonId)
        setsearchBarType(serachBarButtonId)
      }
      
      // API calls
      useEffect(() => {
        Request(setResults, searchBarType, setLoading)
      }, [searchBarType])

      // Get current results 
      const indexOfLastResult = currentPage * resultsPerPage;
      const indexOfFirstResult = indexOfLastResult - resultsPerPage;
      const currentResults = results.slice(indexOfFirstResult, indexOfLastResult);

      // Change page
      const paginate = (pageNumber) => setCurrentPage(pageNumber); 


      return (
        <div className="App">
          <SearchBar handleClick={handleClick} />
          <Results results={currentResults} loading={loading} />
          <Pagination resultsPerPage={resultsPerPage} totalResults={results.length} paginate={paginate} />
        </div>
      );
    }

    export default App;

我希望它看起来足够通用,可以遵循指南。请问我任何有助于澄清的问题。我花了8-10个小时寻找并试图解决这个问题……

EN

回答 1

Stack Overflow用户

发布于 2021-02-22 08:55:39

您可以继续使用您的过滤器,但您必须进行一些更改,对于component PaginationtotalResults属性,您必须设置500行,以便用户可以选择他想要的页面,因为如果您设置了10行,用户可以选择的页面是1、2、3、4,但是我们不需要将所有页面都放入1到34页,因为我们有500个ids。第二点,我们需要从服务器逐页获取数据,页面大小等于3,我们需要传递给Request startIndexlastIndex来请求。

Request.js

代码语言:javascript
复制
import axios from 'axios';
    import BottleNeck from 'bottleneck'

    const limiter = new BottleNeck({
      maxConcurrent: 1, 
      minTime: 333
    })


    export const Request = (setResults, searchBarType, setLoading, startIndex, lastIndex) => {
      
      const searchBar = type => {
        const obj = {
          'new': 'newstories',
          'past': '',
          'comments': 'user',
          'ask': 'askstories',
          'show': 'showstories',
          'jobs': 'jobstories',
          'top': 'topstories',
          'best': 'beststories',
          'user': 'user'
        }
      
        return obj[type] ? obj[type] : obj['new'];
      }

      let type = searchBar(searchBarType)

      const getData = () => {
        const options = type
        const API_URL = `https://hacker-news.firebaseio.com/v0/${options}.json?print=pretty`;

        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }

      const getIdFromData = (dataId) => {
        const API_URL = `https://hacker-news.firebaseio.com/v0/item/${dataId}.json?print=pretty`;
        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }


      const runAsyncFunctions = async () => {
        setLoading(true)
        const {data} = await getData()
        let ids = data.slice(firstIndex, lastIndex+1) // we select our ids by index

        Promise.all(
          ids.map(async (d) => {
            const {data} = await limiter.schedule(() => getIdFromData(d))
            console.log(data)
            return data;
          })
          )
          .then((newresults) => setResults((results) => [...results, ...newresults]))
          setLoading(false)
        // make conditional: check if searchBar type has changed, then clear array of results first
      }  
      

      runAsyncFunctions()
    }

App.js

代码语言:javascript
复制
import React, { useState, useEffect } from 'react';
    import './App.css';
    import { SearchBar } from './search-bar';
    import { Results } from './results';
    import { Request } from '../helper/request'
    import { Pagination } from './pagination';

    function App() {
      const [results, setResults] = useState([]);
      const [searchBarType, setsearchBarType] = useState('news');
      const [loading, setLoading] = useState(false);
      const [currentPage, setCurrentPage] = useState(1);
      const [resultsPerPage] = useState(3);
      

      // Select search bar button type 
      const handleClick = (e) => {
        const serachBarButtonId = e.target.id;
        console.log(serachBarButtonId)
        setsearchBarType(serachBarButtonId)
      }
      
      // API calls
      useEffect(() => {
        Request(setResults, searchBarType, setLoading, 0, 2) //we fetch the first 3 articles
      }, [searchBarType])

     

      // Change page
      const paginate = (pageNumber) => {
           // Get current results 
          const indexOfLastResult = currentPage * resultsPerPage;
          const indexOfFirstPost = indexOfLastResult - resultsPerPage;
          Request(setResults, searchBarType, setLoading, indexOfFirstPost , indexOfLastResult) //we fetch the 3 articles of selected page
          setCurrentPage(pageNumber); 
      }


      return (
        <div className="App">
          <SearchBar handleClick={handleClick} />
          <Results results={results} loading={loading} />
          <Pagination resultsPerPage={resultsPerPage} totalResults={500} paginate={paginate} />
        </div>
      );
    }

    export default App;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66308187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档