The thing I'm doing here is fetching anime characters from anilist graphql api. The reason I've added a loop is so I could fetch data from a certain character id to a limit. For example 1-100. But I want to respect their API rate limits and so I'd like a way to limit my requests to 1 per second. Hence, I've used setTimeout
, but I still got rate-limited from the API and using setInterval
only keeps on looping it every 5 seconds. Like the same data gets fetched every 5 seconds.
Is there any way I can make it as I've mentioned?
My code:
const fs = require("fs");
const number = 3;
const axios = require("axios");
async function fetchData() {
for (let i = 1; i <= number; i ) {
const query = axios
.post(
"https://graphql.anilist.co",
{
query: `query character(
$id: Int
$page: Int
$sort: [MediaSort]
$onList: Boolean
$withRoles: Boolean = false
) {
Character(id: $id) {
id
name {
first
middle
last
full
native
userPreferred
alternative
alternativeSpoiler
}
image {
large
}
favourites
isFavourite
isFavouriteBlocked
description
age
gender
bloodType
dateOfBirth {
year
month
day
}
media(page: $page, sort: $sort, onList: $onList) @include(if: $withRoles) {
pageInfo {
total
perPage
currentPage
lastPage
hasNextPage
}
edges {
id
characterRole
voiceActorRoles(sort: [RELEVANCE, ID]) {
roleNotes
voiceActor {
id
name {
userPreferred
}
image {
large
}
language: languageV2
}
}
node {
id
type
isAdult
bannerImage
title {
userPreferred
}
coverImage {
large
}
startDate {
year
}
mediaListEntry {
id
status
}
}
}
}
}
}`,
variables: {
id: i,
withRoles: false,
},
},
{
headers: {
"Content-Type": "application/json",
},
}
)
.then((response) => {
// console.log(response.data.data.Character)
const jsonContent =
JSON.stringify(response.data.data.Character, null, 4) ", ";
fs.appendFile("./chars.json", jsonContent, function (err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
})
.catch((error) => console.log(`Code: ${error}`, error));
}
}
fetchData();
CodePudding user response:
Something like that will work for you (Asuming all the rest was ok):
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function fetchData() {
for (let i = 1; i <= number; i ) {
const query = axios.post(
"https://graphql.anilist.co",
{
query: someQuery, // TODO: Set your query here
variables: {
id: i,
withRoles: false
}
},
{
headers: {
"Content-Type": "application/json"
}
}
);
let response;
try {
response = await query;
} catch (e) {
console.log(`Code: ${e}`, e);
return; // or handle in some different way
}
const jsonContent =
JSON.stringify(response.data.data.Character, null, 4) ", ";
fs.appendFile("./chars.json", jsonContent, function (err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
await delay(5000); // TODO: Change to whatever you need
}
}