如何限制我基于浏览器的应用程序的API请求?

时间:2019-06-19 14:48:39

标签: javascript

我正在开发一个基于浏览器的应用,以从https://api.discogs.com/查找和下载数据(以.csv文件的形式)。

在成功进行了包含几个要查找的输入文件的试用之后,我尝试升级到包含30行或更多行的较大输入文件,但是我得到了this error。看来我超出了指定的here比率。

那么如何如上所述在本地限制我的应用程序的请求?

我想我需要添加的代码将是以下部分中的一个或多个:

const request = new XMLHttpRequest();
request.open('GET',
`https://api.discogs.com/releases/${searchDetails}`);
request.send();

    function getReleases(id) {
      const request = new XMLHttpRequest();
      request.open('GET',
      `https://api.discogs.com/releases/${id}`);
      request.send();

function getRelease(id) {
  return fetch(`https://api.discogs.com/releases/${id}`,
    {
      headers: {
        'User-Agent': 'CSV for Discogs/0.1',
      }
    })
    .then(response => response.json())
    .then(parseReleaseData)
  }

TIA

编辑:另一个论坛上的某人建议使用Window setInterval()方法,但我不确定如何编码。如果可以,请说...

setInterval(getRelease(), 1000);

function getRelease(id) {
  return fetch(`https://api.discogs.com/releases/${id}`,
    {
      headers: {
        'User-Agent': 'CSV for Discogs/0.1',
      }
    })
    .then(response => response.json())
    .then(parseReleaseData)
  }

...不会陷入循环,试图每秒重复运行代码吗?

Edit2:我尝试过,但是它甚至在我没有机会向应用程序输入任何数据之前就陷入了与API服务器的循环。

1 个答案:

答案 0 :(得分:3)

最简单的方法是保持承诺链以跟踪请求:

  const timer = ms => new Promise(resolve => setTimeout(resolve, ms));

  let requests = Promise.resolve();

  function getRelease(id) {
   const apiCall = requests.then(() =>
    fetch(`https://api.discogs.com/releases/${id}`, {
      headers: {
        'User-Agent': 'CSV for Discogs/0.1',
      }
    })   
   );

   // add to chain / queue 
   requests = apiCall.then(response => 
    +response.headers.get("X-Discogs-Ratelimit-Remaining") <= 1 && timer(60 * 1000)
   );

   return apiCall
     .then(response => response.json())
     .then(parseReleaseData);
  }

现在将一个接一个地执行一个请求,如果达到速率限制,则将等待一分钟。

如果速率限制错误,您可能想重试。您还可以添加多个Promise队列,以提高吞吐量。