I've been getting more into the internals of the Node.js architecture, and a term I see coming up a lot is "tick" as in "next tick of the event loop" or the function nextTick().
What I haven't seen is a solid definition of what exactly a "tick" is. Based on various articles (such as this one), I've been able to piece a concept together in my head, but I'm not sure how accurate it is.
Can I get a precise and detailed description of a Node.js event loop tick?
In Node. js, each iteration of an Event Loop is called a tick. To schedule a callback function to be invoked in the next iteration of the Event Loop, we use process.
JavaScript has a runtime model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks. This model is quite different from models in other languages like C and Java.
In computer science, the event loop is a programming construct or design pattern that waits for and dispatches events or messages in a program.
Event Loop uses Single Thread only. It is main heart of Node JS Platform Processing Model. Even Loop checks any Client Request is placed in Event Queue.
Remember that while JavaScript is single-threaded, all of node's I/O and calls to native APIs are either asynchronous (using platform-specific mechanisms), or run on a separate thread. (This is all handled through libuv.)
So when there's data available on a socket or a native API function has returned, we need a synchronized way to invoke the JavaScript function that is interested in the particular event that just happened.
It's not safe to just call the JS function from the thread where the native event happened for the same reasons that you'd encounter in a regular multi-threaded application – race conditions, non-atomic memory access, and so forth.
So what we do is place the event on a queue in a thread-safe manner. In oversimplified psuedocode, something like:
lock (queue) { queue.push(event); }
Then, back on the main JavaScript thread (but on the C side of things), we do something like:
while (true) { // this is the beginning of a tick lock (queue) { var tickEvents = copy(queue); // copy the current queue items into thread-local memory queue.empty(); // ..and empty out the shared queue } for (var i = 0; i < tickEvents.length; i++) { InvokeJSFunction(tickEvents[i]); } // this the end of the tick }
The while (true)
(which doesn't actually exist in node's source code; this is purely illustrative) represents the event loop. The inner for
invokes the JS function for each event that was on the queue.
This is a tick: the synchronous invocation of zero or more callback functions associated with any external events. Once the queue is emptied out and the last function returns, the tick is over. We go back to the beginning (the next tick) and check for events that were added to the queue from other threads while our JavaScript was running.
What can add things to the queue?
process.nextTick
setTimeout
/setInterval
fs
, net
, and so forth)crypto
's processor-intensive functions like crypto streams, pbkdf2, and the PRNG (which are actually an example of...)A simpler answer for those new to JavaScript:
The first thing to understand is that JavaScript is a "single-threaded environment". This refers to JavaScript's behavior of executing your blocks of code one at a time from "the event loop" on a single thread. Below there's a rudimentary implemenation of the event loop taken from Kyle Simpson's book ydkJS and afterwards, an explanation:
// `eventLoop` is an array that acts as a queue (first-in, first-out) var eventLoop = [ ]; var event; // keep going "forever" while (true) { // perform a "tick" if (eventLoop.length > 0) { // get the next event in the queue event = eventLoop.shift(); // now, execute the next event try { event(); } catch (err) { reportError(err); } } }
The first while loop simulates the event loop. A tick is the dequeuing of an event from the "event loop queue" and the execution of said event.
Please see the response of 'Josh3796' for a more detailed explanation of what happens in the dequeuing and execution of an event.
Also, I recommend reading Kyle Simpson's book for those who are interested in getting a deep understanding of JavaScript. It's completely free and open-source and can be found at this link: https://github.com/getify/You-Dont-Know-JS
The specific section I referenced can be found here: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/sync-async/ch1.md
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With