Home > Back-end >  set timer inside a loop for graphql query
set timer inside a loop for graphql query

Time:07-22

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
  }
}
  • Related