The setTimeout method can be used to delay the calling of a function, that is I can call the setTimeout method, pass a function as the first argument, an amount of time in milliseconds as the second argument. The result of doing so is that the function that I passed as the first argument will fire when an amount of time greater than or equal to the amount of time I passed has elapsed. The function calling is not always guaranteed to fire at that time mind you though, so it is more of a target time. The setTimeout method is one option for setting up a situation in which a function keeps getting called over and over again at a certain rate by placing setTimeout in the function that will be called by setTimeout.
1 - Some setTimeout basic examples
I enjoy the process of learning by doing rather than by other means, and I think that learning by doing might be the best options for getting a knowledge of something solid. In this section I will be covering some basic use case examples of setTimeout. The basic idea is not that hard, just call the method, and pass the method that is to be called after a set amount of time as the first argument, followed by the amount of time in milliseconds. The function is then called once the set amount of time passes, and that is basically all there is to it. Of course there is more to it than just that in many different use case examples, but I will be getting getting to some of that later in this post.
1.1 - The source code examples here are on my github
1.2 - Delay the call of a function with setTimeout
So not it might be called for to start out with just a really basic example of the set time out method. So to just simply delay the call of a function I just need to pass the function, and the amount of time when calling setTimeout like this.
1.3 - A basic loop
To put together a basic loop all I need to do is call the setTimeout method in the body of the method that I pass to setTimeout resulting in a kind of recursion. In many projects it is necessary to define this kind of function to have a situation in which some kind of state is updated on each frame tick.
So in this example I am just stepping an x variable by a static delta value each time the loop function is called by setTimeout which should be roughly every 30 milliseconds. This might be a good starting point when it comes to getting the basic idea of what a main app loop is for a project, but when it comes to making a real project this kind of approach might not be the best way to go about doing so. The amount of time that passes might not always be 30 milliseconds here, that is the main reason why I say that, on top of other reasons why. However I just wanted to cover a basic example of an app loop here in this section, I will be getting to some more advanced examples of setTimeout later.
1.4 - clearTimeout
If I want to stop setTimeout from continuing there is the clearTiemout method that can be used to do so. To use it I just need to pass the timeoutID returned when calling setTimeout to clearTimeout as the first argument.
1.5 - A loop using a state object, dates, and an update method
Now it is time for a not so basic, basic example of a loop using set time out. This time I am using the Date class to create a last time date object. Inside the body of the loop method I am creating another date object and creating a time delta from the last time date object stored in a state object. I can create this time delta in the from of a sections value by just subtracting the last time from the current time and then dividing that result by one thousand. I can then check to see if this sections value is higher than a seconds value that is a desired frame to tick rate, if so I call an update method, and set the lat time date object back to the current time. When I call the update method I can then pass the state object along with a seconds value that can be used as a way to update the state of something such as the position of an object.
2 - Browser throttling of setTiemout when a tab is inactive
So one of the few reasons why setTimeout and setInterval are still useful alternatives to that of requestAnimationFrame is that it behaves differently when it comes to inactive windows. For example if I am making some kind of game where I want logic to be called every so often even when the window in which the game is running is not active I can do so with setTimeout, where with requestAnimationFrame the loop would be paused.
2.1 - A log to title demo
When I run this the money value steps at a fairly fast rate as expected, but once I switch tabs it slows down to a rate of about one frame tick per second in chrome 70.x. Although the rate at which setTimeout runs is slowed down, it does still run, unlike with requestAnimationFrame. Still because of this nature I will want to design my code accordingly. As such in this example I should step money at a perSecondRate and find out the about of time that elapses each second.
3 - Change over time example of setTimeout
The basic idea here is that I have a variable outside of the loop that stores a Date object time stamp that is the last time that the state object was updated. In the body of the function that is passed to setTimeout I can create another Date object that is the current time, this value can be used with the last time value that will give an amount of time that has passed sense the state was updated last. I can then use the value to update the state of a value based on time rather that just steeping forward by a fixed amount. Once that is done I can set my last time value to the current date time stamp.
4 - Conclusion
Using settimeout is by no means the only tool in the toolbox when it comes to setting up this kind of loop. There are several other options such as setinterval, and requestAnimationFrame, but the topic goes beyond that. When using any of these methods in a single event loop that is not the same thing as using them in a collection of event loops when it comes to things like webworker, or the cluster module, or the child process module in nodejs. Thos are of course ways to go about working with more than one event loop, which goes beyond just using set time out by itself in a single event loop.