Skip to content
FLAVIO COPES
flaviocopes.com

How to make your JavaScript functions sleep

By

Learn how to make a JavaScript function sleep for a set time, since the language has no native sleep, by wrapping setTimeout in a promise and using async/await.

~~~

JavaScript has no built-in sleep function, but you can build one by wrapping setTimeout() in a promise and awaiting it. Your function pauses, and the rest of the program keeps running.

In a programming language like C or PHP, you’d call sleep(2) to make the program halt for 2 seconds. Java has Thread.sleep(2000), Python has time.sleep(2), Go has time.Sleep(2 * time.Second).

Why doesn’t JavaScript have this? Because JavaScript runs on a single thread. If a function could block that thread, the browser would freeze the whole page while waiting. No clicks, no rendering, nothing.

Thanks to promises and async/await (introduced in ES2017) we can get the same result without blocking anything:

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

This wraps setTimeout() in a promise. The promise resolves after the number of milliseconds you pass, and nothing else happens in the meantime.

In Node.js you can write it in an even shorter way:

const { promisify } = require('util')
const sleep = promisify(setTimeout)

See more on promisify

How to use the sleep function

You can use it with the then callback:

sleep(500).then(() => {
  //do stuff
})

Or, more readable, in an async function:

const doSomething = async () => {
  await sleep(2000)
  //do stuff
}

doSomething()

The await line pauses doSomething() for 2 seconds, then execution continues.

Remember that due to how JavaScript works (read more about the event loop), this does not pause the entire program execution like it might happen in other languages, but instead only your function sleeps. Timers and other events keep firing normally.

Sleeping inside a loop

You can apply the same concept to a loop, to add a delay between iterations:

const list = [1, 2, 3, 4]
const doSomething = async () => {
  for (const item of list) {
    await sleep(2000)
    console.log('🦄')
  }
}

doSomething()

This prints a unicorn every 2 seconds, four times. I use this pattern when I call a rate-limited API and need to space out the requests.

Be careful with forEach()

A common mistake is to use forEach() instead of for...of:

list.forEach(async (item) => {
  await sleep(2000)
  console.log('🦄')
})

This does not work as you’d expect. forEach() does not wait for the async callback to finish. All 4 iterations start at the same time, and all 4 unicorns print together after 2 seconds.

If you need the iterations to run one after the other, use for...of like in the previous example.

~~~

Related posts about js: