setInterval(), how does it work?

function randomSelect(){
    const times = 15
    const inter = setInterval(()=> {
        const randomTag = pickRandomTag()
        highlightTag(randomTag)
        setTimeout(()=>{
            unhighlightTag(randomTag)
        },200)
    
    },200)
    
    console.log("test")
    setTimeout(()=>{
     clearInterval(inter)   
     setTimeout(()=>{
         const randomTag = pickRandomTag()
         highlightTag(randomTag)
     },100)
    }, times * 100)
}

My question here is, when setInterval is run once, does it run in the background each 200ms until it is stopped. Because the consol.log is executed even when setInterval is running. Is js running that simultaniously?

Without getting deeply into how JS handles it, setTimeout will run once and setInterval will run forever, unless that timer is cleared.
For example, the following code:

const baseTime = Date.now()
const getElapsed = () => `after ${(Date.now() - baseTime)/1000} seconds`

const interval1 = setInterval(() => console.log('Interval 1', getElapsed()), 2000)
const interval2 = setInterval(() => console.log('Interval 2', getElapsed()), 5000)
setTimeout(() => console.log('Timeout 1', getElapsed()), 3000)
setTimeout(() => console.log('Timeout 2', getElapsed()), 4000)

setTimeout(() => clearInterval(interval1), 10000)
setTimeout(() => clearInterval(interval2), 20000)

This gives the output:

Interval 1 after 2.004 seconds
Timeout 1 after 3.004 seconds
Interval 1 after 4.98 seconds
Timeout 2 after 4.981 seconds
Interval 2 after 6.178 seconds
Interval 1 after 6.178 seconds
Interval 1 after 8.841 seconds
Interval 1 after 10.004 seconds
Interval 2 after 10.004 seconds
Interval 2 after 15.002 seconds
Interval 2 after 20.004 seconds

Note that without those last two lines of code, the intervals would run forever, or at least until the app is terminated.

How does it work on a deeper level? I believe that while JS is single threaded, the browser can run a separate thread dealing with timing events. At the defined interval, the relevant events are pushed onto the JS event queue and are handled as they come in the JS event loop. When we called setInterval like setInterval(myFunc, interval), the environment knows to push myFunc onto the JS event queue every x number of milliseconds, as defined by interval.

I suspect that the implementation will depend on the browser/engine involved.
I don’t think JS defines how it is done, just that compliant engines give this result. That’s my understanding anyway. Obviously the implementation will be different for a browser running on Windows and Node running on Linux, but as long as it meets the JS specs, we don’t care how it is happening.

1 Like

Thanks a lot, I got a better understanding with that explanation!