Spe*_*est 5 node.js deezer axios
我正在使用axios向Deezer API发出请求。不幸的是,使用Deezer的API,当您请求歌手的专辑时,它不包含专辑曲目。因此,我正在通过请求艺术家的专辑,然后为每个专辑执行后续axios请求来解决此问题。我遇到的问题是,API将请求限制为每5秒50个请求。如果一个艺术家有50张以上的专辑,我通常会收到“超出配额”错误。有没有一种方法可以将axios请求限制为每5秒50个,特别是在使用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);
Run Code Online (Sandbox Code Playgroud)
这是我使用简单的异步 setTimeout / Es6 代码的解决方案:
您可以在睡眠参数函数中设置延迟
const sleep = (delay) => {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
axios.interceptors.response.use(async function (response) {
await sleep(3000)
return response;
}, function (error) {
// Do something with response error
console.error(error)
return Promise.reject(error);
});
Run Code Online (Sandbox Code Playgroud)
您还可以使用这个 npm 包: https: //www.npmjs.com/package/axios-request-throttle
首先,让我们看看您真正需要什么。如果您有大量相册,这里的目标是最多每100毫秒发出一次请求。(使用axios.all此方法与使用并无区别Promise.all,您只想等待所有请求完成。)
现在,有了axios,您就有了拦截API,可以在请求之前插入逻辑。因此,您可以使用这样的拦截器:
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);
}
Run Code Online (Sandbox Code Playgroud)
它所做的是计时请求,因此它们以intervalMs毫秒为间隔执行。
在您的代码中:
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);
}
Run Code Online (Sandbox Code Playgroud)
但是,这是一种简单的方法,对于您的情况,对于少于50个的请求,您可能希望尽快接收结果。为此,您必须在调度程序中添加某种计数器,该计数器将对请求的数量,并根据时间间隔和计数器延迟执行时间。