Explain Codes LogoExplain Codes Logo

Javascript sleep/wait before continuing

javascript
async-await
promise-engineering
callbacks
Anton ShumikhinbyAnton Shumikhin·Jan 2, 2025
TLDR

Achieve a delay or pause in your JavaScript code execution by leveraging the async/await pattern in combination with our bespoke sleep function:

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); async function delayedLog() { console.log('Waiting is the hardest part...'); await sleep(2000); // 2-second pause, like waiting in line for coffee ☕ console.log('Finally, my turn!'); } delayedLog();

Executing console.log('Waiting is the hardest part...') initiates the process. After a patient wait of 2 seconds, our script bustles and confidently states console.log('Finally, my turn!').

A peek under the hood: Understanding async/await

An async function yields a Promise. That's cool, but when coupled with an await expression, it delivers extra oomph by pausing the execution of asynchronous functions. It feels like calling 'timeout' in a board game until the Promise resolution or rejection.

However, it doesn't keep you waiting long. Once the promise comes through, it briskly resumes the function's execution and dutifully returns the resolved value. Like waiting for a very punctual but important email.

Potential pitfalls with sleep calls

When working with sleep functions, like too much of a good thing, timing can become that slowly loading GIF. Dealing with sleep times needs balance, like coffee consumption. Excessive waiting is like a YouTube ad with no skip button - it's a bad user experience.

Practical applications for sleep/wait

Temporary user notifications

Wait times = read times. A delay before updating a notification gives your users a moment to soak it in.

Smoother animation sequences

A bit of a nap between animation stages ensures they're observed individually, providing a more natural user interaction.

API calls and throttling

Gentle pacing of operations such as API calls or intense calculations ensures neither you nor the system has a meltdown due to overload.

Common gotchas and their solutions

Misunderstanding setTimeout

Remember, setTimeout isn't an espresso shot - it won't pause code execution. This isn't an Italian café!

Callback inception

Beware of the callback inception (aka callback hell). Maintain your code readability by avoiding deep nesting of setTimeout callbacks.

Blocking the main thread

Avoid synchronous for loop sleeps. It's like an internet troll, it will make things unresponsive and create havoc.

Out-of-the-box solutions

Promise-based timing

You can be a hipster and avoid async/await - use chained Promises with .then instead:

function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } console.log('Sit tight...'); sleep(2000).then(() => { console.log('Surprise! 🎉'); });

Generators

For complex control flows, JavaScript Generators can juggle sleep functionality to pause and resume execution:

function* generatorSleepWorkflow() { console.log('Step 1: Draw two circles ⚫⚫'); yield sleep(2000); console.log('Step 2: Draw the rest of the owl 🦉'); yield sleep(2000); console.log('Art!'); } const iterator = generatorSleepWorkflow(); iterator.next().value.then(() => iterator.next());

setInterval: Use with caution!

setInterval is like setting your own alarm - wake up every X period unless stopped. Ran without control, it can turn into a Groundhog Day nightmare scenario. Always remember to call clearInterval.

References