限制 Axios 请求 [英] Throttling Axios Requests

查看:41
本文介绍了限制 Axios 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 axios 向 Deezer API 发出请求.不幸的是,使用 Deezer 的 API,当您请求艺术家的专辑时,它不包括专辑曲目.因此,我通过请求艺术家的专辑然后对每张专辑执行后续 axios 请求来解决这个问题.我遇到的问题是 API 将请求限制为每 5 秒 50 个.如果一位艺术家的专辑超过 50 张,我通常会收到超出配额"的错误消息.有没有办法将 axios 请求限制为每 5 秒 50 个,特别是在使用 axios.all 时?

I'm using axios to make requests to the Deezer API. Unfortunately, with Deezer's API when you request an artist's albums it does not include album tracks. So, I am working around this by requesting the artist's albums and then performing a subsequent axios request for each album. The problem I'm running into is that the API limits requests to 50 per 5 seconds. If an artist has more than 50 albums I usually get a "quota exceeded" error. Is there a way to throttle axios requests to 50 per 5 seconds, specifically when using axios.all?

var axios = require('axios');

function getAlbums(artistID) {
  axios.get(`https://api.deezer.com/artist/${artistID}/albums`)
    .then((albums) => {
      const urls = albums.data.data.map((album) => {
        return axios.get(`https://api.deezer.com/album/${album.id}`)
          .then(albumInfo => albumInfo.data);
      });
      axios.all(urls)
        .then((allAlbums) => {
          console.log(allAlbums);
        });
    }).catch((err) => {
      console.log(err);
    });
}

getAlbums(413);

推荐答案

首先,让我们看看您真正需要什么.如果您有大量专辑,您的目标是最多每 100 毫秒发出一次请求.(在这件事上使用 axios.all 与使用 Promise.all 没有什么不同,你只是想等待所有请求完成.)

First of all, let's see what you really need. Your goal here is to make request at most each 100 milliseconds, if you have a large number of albums. (Using axios.all for this matter is no different from using Promise.all, you just want to wait for all of the requests to complete.)

现在,有了 axios,你就有了拦截 API,允许在请求之前插入你的逻辑.所以你可以像这样使用拦截器:

Now, with axios you have the interception API, allowing to plug your logic before requests. So you can use an interceptor like this:

function scheduleRequests(axiosInstance, intervalMs) {
    let lastInvocationTime = undefined;

    const scheduler = (config) => {
        const now = Date.now();
        if (lastInvocationTime) {
            lastInvocationTime += intervalMs;
            const waitPeriodForThisRequest = lastInvocationTime - now;
            if (waitPeriodForThisRequest > 0) {
                return new Promise((resolve) => {
                    setTimeout(
                        () => resolve(config),
                        waitPeriodForThisRequest);
                });
            }
        }

        lastInvocationTime = now;
        return config;
    }

    axiosInstance.interceptors.request.use(scheduler);
}

它所做的是计时请求,因此它们以 intervalMs 毫秒的间隔执行.

What it does is timing requests so they are performed at intervalMs milliseconds intervals.

在您的代码中:

function getAlbums(artistID) {
    const deezerService = axios.create({ baseURL: 'https://api.deezer.com' });
    scheduleRequests(deezerService, 100);

    deezerService.get(`/artist/${artistID}/albums`)
        .then((albums) => {
            const urlRequests = albums.data.data.map(
                    (album) => deezerService
                        .get(`/album/${album.id}`)
                        .then(albumInfo => albumInfo.data));

            //you need to 'return' here, otherwise any error in album
            // requests will not propagate to the final 'catch':
            return axios.all(urls).then(console.log);
        })
        .catch(console.log);
}

然而,这是一种简单的方法,在您的情况下,您可能希望在请求数量少于 50 时尽快收到结果.为此,您必须在调度程序中添加某种计数器它将根据间隔和计数器计算请求的数量并延迟它们的执行.

This is, however, a simplistic approach, in your case you probably would like to receive the results as fast as possible for number of requests less than 50. For this, you have to add some kind of a counter inside the scheduler which will count the number of requests and delay their execution based both on the interval and the counter.

这篇关于限制 Axios 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆