Logo with initials
Click me x5 ↓

Throttle a series of promises with sleep()

I often find myself wanting to run a series of JavaScript promises and wait between them.

For example, you might want to call an API for each item in a list. Like this:

for (const bookID of bookIDs) {
  // Don't do this
  const bookData = await getBookDataFromAPI(bookID);
  console.log('Downloaded data for ', bookData.title);
}

The problem is, this each iteration of the loop will execute as soon as possible. There are 2 reasons why you don’t want this:

  1. You don’t want to overwhelm the server and get your key revoked or your IP blacklisted.
  2. It’s not nice.

I use a sleep function that halts the execution of a promise for a specific duration, then resolves it. I kept this habit from doing creative coding, as both Processing and Arduino have an equivalent. I like doing it because it’s a convenient, readable way of understanding what’s going on. It’s a one-liner:

const sleep = (t) => new Promise((resolve) => setTimeout(resolve, t));

Then you can do

await sleep(500);

Back to our API example. You’ll need to use for...of loops, because they’ll wait for promises to resolve before continuing.

const sleep = (t) => new Promise((resolve) => setTimeout(resolve, t));

// You must use a `for...of` loop, a regular loop won't wait for the promise to resolve.
for (const bookID of bookIDs) {
  // Do this instead, wait between API calls
  const bookData = await getBookDataFromAPI(bookID);
  await sleep(500);

  console.log('Downloaded data for ', bookData.title);
}