API请求分页

API请求分页,api,reactjs,github,axios,Api,Reactjs,Github,Axios,我向Github发出一个简单的API请求,以获取所有存储库。问题是Github有一个限制,每个请求最多可以发送100个。有超过100个存储库的用户,我不知道如何访问它或如何进行分页 我使用Axios发出GET请求,如下所示: https://api.github.com/users/<AccountName>/repos?per_page=100 您可以通过首先从用户帐户URL请求来获取回购数量。例如,我的: 其中的响应包括“公共回购”值。砰!这就是你想要的神奇数字 如果回购数量

我向Github发出一个简单的API请求,以获取所有存储库。问题是Github有一个限制,每个请求最多可以发送100个。有超过100个存储库的用户,我不知道如何访问它或如何进行分页

我使用Axios发出GET请求,如下所示:

https://api.github.com/users/<AccountName>/repos?per_page=100

您可以通过首先从用户帐户URL请求来获取回购数量。例如,我的:

其中的响应包括“公共回购”值。砰!这就是你想要的神奇数字

如果回购数量超过100,您接下来需要进行多次回迁。我知道你不想,但是嘿。。。不能责怪web服务试图节省带宽。好消息是,您可以将它们放在Promise.all()块中,让它们集合在一起并立即返回。所以代码就像

const fetchAllTheRepos = (userName, repoCount) => {
  const MAX_PER_PAGE = 100;
  const baseUrl = 'https://api.github.com/users/' + userName +
    '/repos?per_page=' + MAX_PER_PAGE;

  //Start fetching every page of repos.
  const fetchPromises = [], pageCount = Math.ceil(repoCount / 
    MAX_PER_PAGE);
  for (let pageI = 1; pageI <= pageCount; ++pageI) {
    const fetchPagePromise = fetch(baseUrl + '&page=' + pageI);
    fetchPromises.push(fetchPagePromise);
  }

  //This promise resolves after all the fetching is done.
  return Promise.all(fetchPromises)
  .then((responses) => {
     //Parse all the responses to JSON.
     return Promise.all( responses.map((response) => response.json()) );
  }).then((results) => {
    //Copy the results into one big array that has all the friggin repos.
    let repos = [];
    results.forEach((result) => {
      repos = repos.concat(result);
    });
    return repos;
  });
};

//I left out the code to get the repo count, but that's pretty easy.
fetchAllTheRepos('erikh2000', 7).then((repos) => {
    console.log(repos.length);
});
const fetchAllTheRepos=(用户名,repoCount)=>{
每页最大常数=100;
常量baseUrl=https://api.github.com/users/“+用户名+
“/repos?每页=”+MAX_每页;
//开始获取每页回购协议。
const fetchPromissions=[],pageCount=Math.ceil(repoCount/
每页的最大值);
对于(让pageI=1;pageI{
//解析对JSON的所有响应。
返回Promise.all(responses.map((response)=>response.json());
})。然后((结果)=>{
//将结果复制到一个包含所有friggin repo的大数组中。
设回购利率=[];
results.forEach((结果)=>{
回购=回购成本(结果);
});
回购回报;
});
};
//我省略了获取回购数量的代码,但这很容易。
fetchAllTheRepos('erikh2000',7)。然后((回购)=>{
控制台日志(repos.length);
});
同时获取所有页面可能会超出Github希望您一次为那些拥有大量回购的账户所做的事情。我会对你一次尝试获得的回购数量设置一些“好公民”限制,例如1000。然后通过观察HTTP错误响应,看看api.github.com是否同意您对好公民的定义。如果需要的话,您可以进入节流解决方案,但像上面这样的“一次抓住它”方法可能会很好


另一方面,如果您在一个会话中浏览多个帐户,那么可能从一开始就设计节流,直到您知道。。。好一点。为此,请查看队列/工作者模式。

您是否有任何代码,是否尝试过对请求进行睡眠?嗨,Mike Tunk。我用代码更新了问题。谢谢Erik。我将对此进行检查。是的,我也首先获取用户,然后从用户获取链接并获取存储库。我用我的代码示例更新了这个问题。我现在要把你的公司合并。让我们把孩子带回家吧。如果你也有关于如何将我的观点与你的例子结合起来的建议,请写在这里。我在这里有点不知所措。我还发现有一个npm包
parse link header
,它解析返回的头,在头中有一个总页数和下一页的链接,可以放入api调用并获取数据。我还不知道该怎么用,也许是某种循环。伊戈尔,我想你有所有的零件。我不想将我的代码转换为Axios抓取,但我假设ES6抓取经过一点思考就可以转换过来。您对用户URL(const user=await axios.get(requestUrl,config))的请求将为您提供repo计数(user.data.public_repos),然后您需要与上面我的fetchAllTheRepos()函数相同的逻辑。谢谢Erik。我做到了。您的逻辑工作得很好,我刚刚转换到axios和async/await。谢谢
var config = {
  headers: {'Authorization': `token ${ACCESS_TOKEN}`}
}

const REQUEST: string = 'https://api.github.com/users/'

const apiCall = {
  getData: async function (accountName) {
    const encodedAccountName = encodeURIComponent(accountName)
    const requestUrl = `${REQUEST}${encodedAccountName}`

    const user = await axios.get(requestUrl, config)
// This return user and inside of user there is a link for fetching repos
    const repo = await axios.get(`${user.data.repos_url}?per_page=100`, config)

    ...
const fetchAllTheRepos = (userName, repoCount) => {
  const MAX_PER_PAGE = 100;
  const baseUrl = 'https://api.github.com/users/' + userName +
    '/repos?per_page=' + MAX_PER_PAGE;

  //Start fetching every page of repos.
  const fetchPromises = [], pageCount = Math.ceil(repoCount / 
    MAX_PER_PAGE);
  for (let pageI = 1; pageI <= pageCount; ++pageI) {
    const fetchPagePromise = fetch(baseUrl + '&page=' + pageI);
    fetchPromises.push(fetchPagePromise);
  }

  //This promise resolves after all the fetching is done.
  return Promise.all(fetchPromises)
  .then((responses) => {
     //Parse all the responses to JSON.
     return Promise.all( responses.map((response) => response.json()) );
  }).then((results) => {
    //Copy the results into one big array that has all the friggin repos.
    let repos = [];
    results.forEach((result) => {
      repos = repos.concat(result);
    });
    return repos;
  });
};

//I left out the code to get the repo count, but that's pretty easy.
fetchAllTheRepos('erikh2000', 7).then((repos) => {
    console.log(repos.length);
});