Recursive setTimeout

Devin Pierce
3 min readAug 2, 2018

--

You may be familiar with both the setTimeout and setInterval methods, which allow function calls to be scheduled after a specified delay, or repeatedly at a specified interval. While setInterval fills a useful role, it is somewhat lacking in it’s inability to modify its interval timing after its initial invocation. Which is to say, what if 1000ms is a good amount of time at first, but maybe not later? Or sometimes it is and other times it isn’t, who can anticipate the timing requirements of some future function call? setInterval will tick on forever at the same rate, heedless of my program’s current needs.

A recursive setTimeout provides another way.

The above two functions basically do the same thing. (There is a difference, but I’ll come to that in a moment) However, notice how in the setTimeout example, we revisit the timing parameter on each go around. That means it doesn’t have to stay at 1000ms. It can be whatever we want! Maybe you want the timing to be dependent on some other variable in your program’s current state, or maybe you want it to increase, decrease, or utilize some other mathematical formula, or maybe just be a little random.

Beware though, that since the subsequent setTimeout calls take place within the callback function itself, the execution context may not be able to close, and this can cause an unlimited number of contexts to be added to your call stack.

This can lead to a memory leak, as any variables in the function’s scope will not be cleared from memory until the recursive setTimeout chain is terminated completely, such as with clearTimeout or by simply not perpetuating the recursive call, using conditional logic. This may not be much of an issue if your function’s execution context has a small memory footprint, but it’s worth keeping in mind that no recursive setTimeout chain can be relied on to run forever.

The other distinction between a setInterval call and a recursive setTimeout call is that setInterval delivers its function to the call stack regularly regardless of the status of its previous function calls, while setTimeout will schedule its next call only when its function runs and the new setTimeout is scheduled. So if setInterval was timed to deliver function calls every 1000ms, and the execution of that function takes 300ms, the actual interval between the end of the call and the next invocation would actually be 700ms. If there is any variance in the duration of that execution, that interval will also change, and if the execution takes more time than the interval, you can end up with multiple calls queued back to back. Compare this to a recursive setTimeout, where the next scheduled call will always be delivered after the exact time specified by the previous setTimeout. Neither one of these behaviors is necessarily better than the other, but it’s good to know the difference.

Lastly, for your enjoyment, here is a little recursive setTimeout demonstration I’ve prepared.

--

--