Logo with initials

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) {
  const bookData = await getBookDataFromAPI(bookID);
  console.log('Downloaded data for ', bookData.title);
}

If you have a large list, you don’t want to hammer the API.

There are 2 reasons for 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. It’s a one-liner:

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

Back to our example. you need to use for...of loops, because they 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) {
  const bookData = await getBookDataFromAPI(bookID);
  await sleep(500);

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