The Event Loop
The event loop got its name from how it is implemented; it continues to wait for a message to arrive and then processes the message. Messages added to the event loop follow the queue data structure, which is First In First Out (FIFO). In this case, new messages are added to the bottom of the queue, so that those that entered the event loop first can be processed first.
Have you forgotten how a queue works? Just imagine yourself in a queue at the bank. You’ll get served last if you join the queue last. The event loop works the same way.
In the event loop, each message is processed completely before any other message is processed. This means that once a message is processed, it can’t be paused for another message to be processed. This makes it easy to follow along with the execution of the program. However, a negative implication of this model is that when a message takes too long to complete, it renders the web application redundant (e.g. inability to click or scroll).
Using the event loop means that several events can be added to the queue, and they will be processed in the manner in which they were added to the queue.
Have you thought about how new messages are added to the event loop?
In web browsers, new messages are added based on events that occur. When an event is created, and the event has a listener attached to it, then a new message is added to the event loop. On the other hand, if there is no listener, the event is lost. For example, when a mouse hovers over an element and an event is attached, a new message is added for processing.
Stack: it is a portion of memory reserved for function calls. New functions are added to the stack. When a new function is called, a new stack frame is created. When a function is done processing, it leaves the stack.
Heap: It is a large region of memory reserved for allocating objects.
Queue: It contains messages that are waiting to be processed. When a message is done processing, it leaves the message queue. Each message in the queue is associated with a function that gets executed to handle the message.
At the server side, typically in node.js, the event loop allows the server to perform non-blocking I/O operations. Node.js uses the event loop to manage operations and dispatches them to the operating system kernel whenever possible. Once the operations reach the operating system, the system has its own way of completing the tasks.
setTimeout function allows us to run some specified code after several milliseconds. It takes two arguments; the first argument is a function to run, and the second argument is the number of delays in milliseconds before the function will be pushed into the message queue. The second value is optional, and it defaults to 0. When
setTimeout is called, with the second argument being 0, the function will be pushed into the message queue immediately. Otherwise, the delay would have to elapse before the function is pushed onto the message queue. The
setTimeout function will be pushed onto the message queue immediately after the delay elapses, but it is not guaranteed to process immediately after the delay has elapsed. This is because there may be other functions already in the message queue. And since it’s a queue, the order is First In First Out (FIFO). Therefore, the delay that is set in setTimeout only represents the minimum time but not a guaranteed time.
From the example below, you’ll understand that the function passed to
setTimeout is not guaranteed to run immediately after its time elapses.
SetTimeout doesn’t pause execution
setTimeout function is asynchronous, meaning it does not pause the execution of other call stacks. While the
setTimeout is waiting for the number of delays, other functions can execute without any interference. Consider the code below:
In the example above, the code isn’t executed in the order in which the functions were called. This is due to the way in which
setTimeOut works internally. When the first function is called, the callback function isn’t pushed onto the event queue right away. Instead, it will wait for 5 seconds. While that is happening the second function is called, which in turn will also wait 3 seconds before it is pushed onto the event queue. While the second function is also waiting, the third function is called which waits for 1 second and is then pushed onto the event queue.
After 1 second, the 3rd function call is pushed onto the event queue.
After 3 seconds, the second function call is pushed onto the event queue.
After 5 seconds, the first function call is pushed onto the event queue.
The sequence of execution for the code above will look like this and they will be processed as and when they are pushed to the event queue.
setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. (source mdn). The two methods –
setInterval – are identical except that
setTimeout runs the specified function once, but setInterval continues to run the specified function repeatedly at the set delay.
It is important to note that
Terminate the execution of timers
setInterval creates a function to be executed at a particular time.
The function call can be terminated before execution or can be removed after execution.
When the function call is terminated before execution, the operation is removed from the event loop. It’s good practice to
clearTimeout or clearInterval after the operation is complete. The poll of IDs returned by the two functions are shared so you can use
clearTimeout and clearInterval interchangeably. However, to ensure readability and clarity, it’s best to avoid this interchange.
The code above will work fine since the timerID is shared with
A call to create a timer returns an ID which you can use the cancel the execution of the timer.
Want to be part of the Andela Community? Then join the Andela Talent Network!
If you found this blog useful, check out our other blog posts for more essential insights!