It’s the start of a new year, and while lots of folks are promising to be more active, I’m going to show you how to make Promises to be more lazy…JavaScript Promises, that is.
It’ll make more sense in a moment.
First, let’s look at a basic Promise example. Here I have a function called sleep that takes a time in milliseconds and a value. It returns a promise that will execute a setTimeout for the number of milliseconds that we should wait, then the Promise resolves with the value.
/**
* @template ValueType
* @param {number} ms
* @param {ValueType} value
* @returns {Promise<ValueType>}
*/
function sleep(ms, value) {
return new Promise(resolve => {
setTimeout(resolve, ms, value);
});
}Updated June 6, 2024: Fixed typo. Thanks, Trivikram 🥰
It works like this:

We can await the sleep function with the arguments 1000 and 'Yawn & stretch', and after one second the console will log the string, ‘Yawn & stretch’.
There’s nothing too special about that. It probably behaves as you would expect, but it gets a little weird if we store it as a variable to await later on, rather than awaiting the returned Promise right away.
const nap = sleep(1000, 'Yawn & stretch')Now let’s say we do some other work that takes time (like typing out the next example), and then await the nap variable.

You might expect a one-second delay before resolving, but in fact, it resolves immediately. Anytime you create a Promise, you instantiate whatever asynchronous functionality it’s responsible for.
In our example, the moment we define the nap variable, the Promise gets created which executes the setTimeout. Because I’m a slow typer, the Promise will be resolved by the time we await it.
In other words, Promises are eager. They do not wait for you to await them.
In some cases, this is a good thing. In other cases, it could lead to unnecessary resource use. For those scenarios, you may want something that looks like a Promise, but uses lazy evaluation to only instantiate when you need it.
Before we continue, I want to show you something interesting.
Promises are not the only things that can be awaited in JavaScript. If we create a plain Object with a .then() method, we can actually await that object just like any Promise.