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:
- You don’t want to overwhelm the server and get your key revoked or your IP blacklisted.
- 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);
}