Issues using setTimeout with map to avoid API rate limiting

Viewed 503

I'm working on a project with Spotify's Web API and I'm running into some trouble with hitting rate limits.

I have an array of about 500 artists and I want to loop through the array to get a photo for each artist from Spotify's API using axios. To avoid rate limits, I'm using a setTimeout within the map so there is a half-second delay between each call to the API.

The way I have it set up now, the map triggers all at once and I'm being limited.

Here is the code I'm working with. noPhoto is the array of Artists names. Thanks!

const addArtistSpotifyPhoto = (req, res) => {
  console.log(noPhoto);
  noPhoto.map(e => {
    console.log(e);
    setTimeout(() => {
      axios
        .get(
          `https://api.spotify.com/v1/search?q=${e
            .split(' ')
            .join('%20')}&type=artist&limit=1`,
          {
            headers: { Authorization: `Bearer ${req.user.accessToken}` }
          }
        )
        .then(response => {
          console.log(e, response.data.artists.items.images);
        })
        .catch(console.log);
    }, 500);
  });
};

Solution Edit:

Big shout out to Matti Price's answer. This is how he suggested I fix it, and it works:

const addArtistSpotifyPhoto = (req, res) => {
  console.log(noPhoto);
  noPhoto.map((e, i) => {
    console.log(e);
    setTimeout(() => {
      axios
        .get(
          `https://api.spotify.com/v1/search?q=${e
            .split(' ')
            .join('%20')}&type=artist&limit=1`,
          {
            headers: { Authorization: `Bearer ${req.user.accessToken}` }
          }
        )
        .then(response => {
          console.log(e, response.data.artists.items.images);
        })
        .catch(console.log);
    }, 500 * i);
  });
};
1 Answers

setTimeout is essentially async so it isn't going to wait for the function to fire and then fire the next, it's going to loop through really fast and create all the callbacks to fire in 500ms so they all end up firing at once.

In your map function add in the index, and multiple the delay time by the index so it creates them staggered ever 500 ms.

Related