loading...
Cover image for Simplify code by promisifying `setTimeout`

Simplify code by promisifying `setTimeout`

puruvj profile image PuruVJ Originally published at puruvj.dev ・1 min read

Originally Published @ puruvj.dev

Recently, when I was working on my practice project Microsoft Todo Clone, I needed to implement code like this:

#1 Do Task 1
#2 Wait for 200ms
#3 Do task 2
#4 Wait for 200ms
#5 Do Task 3

Notice #2 and #4. They smell of setTimeoutπŸ˜–. setTimeout takes in a callback, meaning there will be an indentation. Whenever those appear, means the code's gonna get ugly.

So I wrote this code in JS

doTask1();

setTimeout(() => {
  doTask2();

  setTimeout(() => {
    doTask3();
  }, 200);
}, 200);

Now you can see for yourself, this code SMELLS. BAD.

The moment I wrote it, I knew it wouldn't work in long-term. What if I needed to an extra step of waiting and doing a Task #4? Or rearranging the order.

So, I declared a utility function and it solved the problem completely.

/**
 * @param {number} time Time to wait for in milliseconds
 */
function waitFor(time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

Here we're returning a Promise, which resolves when the setTimeout function inside runs.

It's usage would be as simple as

await waitFor(200);

So the spaghetti code above could be rearranged like this:

doTask1();

await waitFor(200);

doTask2();

await waitFor(200);

doTask3();

See how simple it became? It reads exactly like the text version I wrote at the top. It's very idiomatic 😎.

Shorter code

That code snippet could be simplified further

const waitFor = (time) => new Promise((resolve) => setTimeout(resolve, time));

Discussion

pic
Editor guide
 

I'd use the chance to change the time argument to use seconds because who the fuck thought milliseconds were acceptable?

 

You can sure change it. What Mark suggested would work.

However, I disagree with your point. I've used more timers less than 1 second or timeouts like 1.5 seconds that I kinda find the milliseconds method better. Plus its so standard thanks to langs like Java and C and our own JS that any API respecting seconds would feel plain weird

 

I've used more timers less than 1 second or timeouts like 1.5 seconds

What's the problem with sleep(1.5)? I still find that more natural than sleep(1500)

Plus its so standard

No it's not. C uses seconds, the linux command-line program sleep also uses seconds... There's lots of examples out there and milliseconds is far from common.

The only two differences are:

  1. Seconds are the SI base unit.
  2. Seconds are within the orders of magnitude that humans can perceive.

I'd say both of those are clearly benefits of using seconds.

Well, you have a point.

However having seconds measurement in a language that puts milliseconds as first class citizens would incur the cost of context switching.

Thanks for the info

The context switching is precisely why I want this. If you're dealing with seconds in the backend but have to constantly switch to thinking in milliseconds for the frontend code, that's mental work I could spend thinking about the actual code.

 

Change setTimeout(resolve, time) to setTimeout(resolve, time * 1000)

 

Yes, thanks but I was already well aware of how to convert milliseconds to seconds ;D