0

I am trying to fetch an API in a forEach loop but I've got error 429 too many requests. So I want to space these requests out in time and then get all the responses which are blobs and merge them to download one file containing the result of all my requests.

I'm in a simple React app, this is what I did :

In src/services/myBlobBuilder.js

var MyBlobBuilder = function () {
  this.parts = [];
}

MyBlobBuilder.prototype.append = function(part) {
  this.parts.push(part);
  this.blob = undefined;
};

MyBlobBuilder.prototype.getBlob = function() {
  if (!this.blob) {
    this.blob = new Blob(this.parts, { type: "text/plain" });
  }
  return this.blob;
};

export default MyBlobBuilder

In src/services/getBlobForOneMonth.js

const getBlobForOneMonth = async (username, year, month) => {

  return sleep(2000).then(async () =>{
    var requestOptions = {
      method: 'GET',
      redirect: 'follow'
    };

    return await fetch(`https://api.url.com/${username}/${year.toString()}/${month.toString()}`, requestOptions)
      .then( response => {
        return response.blob();
      })
      .catch(error => console.log('error', error));
  })
}

const sleep = ms => {
  return new Promise(resolve => setTimeout(resolve, ms))
}


export default getBlobForOneMonth

In src/services/mergeBlobs.js

import getBlobForOneMonth from './getBlobForOneMonth';
import MyBlobBuilder from './myBlobBuilder';

const mergeBlobs = async (username, months) => {

  var myBlobBuilder = new MyBlobBuilder();
    
  months.forEach(async (month) => {
    const blob = await getBlobForOneMonth(username, month.year, month.month)
    console.log('blob:', blob)
    if (blob.size !== 0){
      myBlobBuilder.append(blob);
    }
    else{
      return;
    }
  })

  const mergedBlob = myBlobBuilder.getBlob()
  return mergedBlob

}

export default mergeBlobs

The months variable is an array containing objects like so :

months = [
  {year: 2021, month: 01},
  {year: 2021, month: 02},
  {year: 2021, month: 03},
  ...
]

So with this code, it looks like the sleep before each request doesn't work properly, the console.log('blob:', blob) appears at the same time in the console. And also my method myBlobBuilder.getBlob() to merge all the blobs is called before the construction of the blob so I end up with an empty blob.

How can I make sure that const mergedBlob = myBlobBuilder.getBlob() after the forEach has done is work? How can I space these requests out in time?

Raphaël
  • 13
  • 3

0 Answers0