DEV Community

Rakshit
Rakshit

Posted on • Edited on

Why you should be careful using setInterval?

If your are here, I am sure that you came across the 2 beautiful Web API's setInterval and setTimeout and want to make an even more deeper dive into understanding them and how they work.

Let us jump into the topic of the post...

I assume that you understand the basic functionalities of setInterval and setTimeout.

Now, before understanding why setInterval is this mischievous guy, we must first remind ourselves that Javascript is a single threaded language i.e. it can perform no more than one task at a time.

Let us take an example to explain the problem with setInterval.

function serverCall() {
    setTimeout(function() {
        console.log('x', new Date().toLocaleTimeString())
    }, 3000)
}

function callServerCall() {
    setInterval(function run() {
        console.log('y', new Date().toLocaleTimeString())
        serverCall()
    }, 1000)
}

callServerCall()


// Output will be
// y 02:00:54
// y 02:00:55
// y 02:00:56
// y 02:00:57
// x 02:00:57
// y 02:00:58
// x 02:00:58
// y 02:00:59
// x 02:00:59
// y 02:01:00
// x 02:01:00
// y 02:01:01
// ..
// ...
Enter fullscreen mode Exit fullscreen mode

You can clearly see that setInterval keeps on running after every 1 second even without caring if the previously called serverCall function was executed or not.

This will prove to be a huge overhead on us because there will be a lot of requests to the server which are queued.

Points to be noted

  • When we call asynchronous operations inside setInterval it will prove to be very costly for us.

  • Even if your async operation takes lesser time than the delay set to the setInterval, the gap between two async calls wouldn't exactly be the delay set. It would be much lesser than that because the time taken to execute the async operation will also be calculated in the delay.

I hope the article helps.

Reach me out on Github and LinkedIn.

Follow me on Twitter

Have a nice day :)

Top comments (2)

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

This isn't so much a problem with setInterval per se as with repeatedly executing (potentially) expensive operations without any supervision.

To prevent this, one could simply build a wrapper like this:

const interval = (callback, timeout) => {
   setTimeout(() => {
      const result = callback()
      if (result && ("then" in result))
         result.then(() => interval(callback, timeout))
      else
         interval(callback, timeout)
   }, timeout)
}
Enter fullscreen mode Exit fullscreen mode

And try it out like this:

interval(() => new Promise(resolve => {
   console.log("Starting...")
   setTimeout(() => {
      console.log("...Finished")
      resolve()
   }, 1e3)
}), 1e3)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
rakshit profile image
Rakshit

Yes using nested setTimeout is one way to bypass this. You anyways gotta be careful when you do this. Thanks for sharing :)