限制 Axios 请求 [英] Throttling Axios Requests
问题描述
我正在使用 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屋!