Looping through an array to make API calls with a delay

I'm admittedly copy pasta-ing this from a few places and not really sure where to troubleshoot:

This is basically a simplification of what I need:

var allData = [];
var emails = ["someone@example", "someoneelse@testing.com"];
loop();

async function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}
async function makeRequests() {
  await query3.trigger({
    additionalScope: {
      personId: emails[i],
    },
  });
   allData.push(query3.data.fullName);
    finalPeople.setValue(allData);
}
async function loop() {
  for (i = 0; i < emails.length; i++) {
    var variant_id = emails[i];
    await delay(10000);
    makeRequests(variant_id);
  }
}

I know that query3 is running correctly because it's returning the expected data based on the email, but it looks like it's running just for the second email in my array because in my temp state, I get an array with two of the same value. It also seems to be running twice for the SECOND value in my email array, leaving the first value just skipped over.

What I'm trying to have happen is take each email in the array (which in real life would be an array outputting from another query, but that's another issue), and then send it through query3. Take that result and push it into a temp state. And with a 10 second delay between API calls because there's a rate limit. I feel like I'm in the ballpark, but not definitely not all the way there.

Any direction would be appreciated! Thanks in advance from a newbie.

1 Like

In your loop() function you are not awaiting the promise returned from makeRequests(). You don't need that delay, unless the endpoint your accessing has request limits.

async function loop() {
  for (i = 0; i < emails.length; i++) {
    var variant_id = emails[i];
    await delay(10000);
    await makeRequests(variant_id);
  }
}

Though your approach will work, it will not scale very well and you're blocking up the processing thread on each request. Basically, this is not running asynchronously.

I would suggest more around making all your requests and awaiting them using a Promise.all() or the like.

This isn't tested, just thinking on a basic approach for you:


hess411

1
11h
I'm admittedly copy pasta-ing this from a few places and not really sure where to troubleshoot:

This is basically a simplification of what I need:

var allData = [];
var emails = ["someone@example", "someoneelse@testing.com"];
loop();

async function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}
async function makeRequests() {
  await query3.trigger({
    additionalScope: {
      personId: emails[i],
    },
  });
   allData.push(query3.data.fullName);
    finalPeople.setValue(allData);
}

/*
async function loop() {
  for (i = 0; i < emails.length; i++) {
    var variant_id = emails[i];
    await delay(10000);
    makeRequests(variant_id);
  }
}
*/

async function loop() {
  const requests = emails.map(email => makeRequests(email));
  await Promise.all(requests);
}

The other functions should probably be refactored a bit, though I am about to get on a plane and don't have time to update. I hope that the updated loop() function shows you a method of making your requests asynchronously where you're waiting for all of them to run and resolve, not run and wait to resolve one at a time.

1 Like