Blog

Blog's main page
FR
Picture of the article: JavaScript Sleep Function with Promise and setTimeout

JavaScript Sleep Function with Promise and setTimeout

Sometimes during development, you need to wait for a minimum amount of time before executing a task. Unlike Python, JavaScript does not have a built-in time.sleep() function, but you can achieve the same behavior using a Promise and setTimeout. In this article, we'll explore how to create a function that waits for a specified time before resolving a Promise.

I often use this approach to simulate an API call or a longer loading process so that the UI can adjust accordingly during data fetching.

Basic sleep function

The sleep function is a really simple function that waits for a minimum amount of time before resolving a Promise.

const sleep = (ms: number) => {
    return new Promise((resolve) => setTimeout(resolve, ms))
};

In the example below, the process is "paused" multiple times before the Promise resolves:

const timeGoesBy = async () => {
    await sleep(2000);
    console.log('2 seconds passed');
    await sleep(2000);
    console.log('4 seconds passed');
    await sleep(2000);
    console.log('6 seconds passed');

    // API call or whatever...
};
timeGoesBy();

Sleep function with an optional custom resolve value

Sometimes, you might want the Promise to resolve with a custom value instead of undefined. You can add an optional parameter to the sleep function. TypeScript helps enforce the type of the returned value.

const sleep = <T = void,>(ms: number, value?: T): Promise<T> => {
    return new Promise((resolve) =>
        setTimeout(() => (undefined === value ? resolve : resolve(value)), ms),
    );
};

In this example below the Promise is resolved with the value 1.

const timeGoesBy = async () => {
    let i = 0;

    i += (await sleep<number>(2000, 1)) ?? 0;
    console.log('2 seconds passed. i = ' + i);
    // 2 seconds passed. i = 1
    
    i += (await sleep<number>(2000, 1)) ?? 0;
    console.log('4 seconds passed. i = ' + i);
    // 4 seconds passed. i = 2
    
    i += (await sleep<number>(2000, 1)) ?? 0;
    console.log('6 seconds passed. i = ' + i);
    // 6 seconds passed. i = 3

    // API call or whatever...
};
timeGoesBy();

A simple React practical example

Let's use the sleep function in a React component to get time to view the loading state. We will use a Suspense component to handle the loading state and the use hook to get the result of the Promise.

import { Suspense, use } from 'react';

type CustomComponentProps = {
    fetchingPromise: Promise<boolean>;
};

// The sleep function
const sleep = <T = void,>(ms: number, value?: T): Promise<T> => {
    return new Promise((resolve) =>
        setTimeout(() => (undefined === value ? resolve : resolve(value)), ms),
    );
};

const SleepExample = () => {
    const apiCall = async () => {
        try {
            // Get time to simulate an asynchronous task...
            return sleep<boolean>(3000, true);
        } catch (error) {
            return false;
        }
    };

    return (
        <Suspense fallback={<div>Loading...</div>}>
            <CustomComponent fetchingPromise={apiCall()} />
        </Suspense>
    );
};

const CustomComponent = ({ fetchingPromise }: CustomComponentProps) => {
    const res = use(fetchingPromise);

    return <div>{res ? 'Resolved' : 'An error occurred'}</div>;
};

export default SleepExample;

Conclusion

A simple use function is a handy tool for simulating asynchronous tasks and or delaying execution in JavaScript. It is especially useful when you need to adjust the UI during data fetching or test loading states in React.

About the author

Front-end developer focused on React, Next.js, and clean, scalable CSS. Once building in PHP, Flash and others, now crafting layouts that (mostly) behave as expected. Greg's background in web design (Photoshop, Illustrator) shaped his love for clean layouts and CSS details. This blog is his way of giving back-sharing what he has learned from the same community that keeps inspiring him.