My question is which thread enqueues event? Is there are a separate thread that does that? If yes can multiple threads enqueue events also?
At it's core, the javascript interpreter is a loop around the select()
sytem call. The select()
system call informs the OS about the filehandles that your program is interested in and the OS will block execution of your program until there are events on any of those filehandles. Basically, select()
will return if there's data on some I/O channel your program is interested in.
In pseudocode, it looks something like this:
while(1) {
select(files_to_write,files_to_read,NULL,NULL,timeout)
process_writable(files_to_write)
process_readable(files_to_read)
timeout = process_timers()
}
This single function allows the interpreter to implement both asynchronous I/O and setTimeout
/setInterval
. (Technically, this is only partly true. Node.js uses either select or poll or epoll etc. based on what functions are available and what functions are more efficient on your OS)
So, who enqueues events? The OS.
There is one exception. Disk I/O on node.js is handled by a separate thread. So for this I/O it is this disk I/O thread that enqueues events to the event loop.
It could be implemented without threads. For example, the Tcl programming language (which predates javascript but also has built-in event loop) implements disk I/O in the main thread using features such as kqueue (on BSD based OS like MacOS) or aio (on Linux and several other OSes) or overlapped-i/o (Windows). But the node.js developers simply chose threading to handle disk i/o.
For more how this works at the C level see this answer: I know that callback function runs asynchronously, but why?
http://127.0.0.1:1337/
the events callback is executed. It's still single threaded, and event driven ? – Haghttp.createServer
function. Which runs in the main thread. Then at the end (after the console.log) the main thread has nothing else to execute so it waits for network I/O. When network I/O happens it dequeues and executes the callback. But in this case dequeue is perhaps a wrong word to use because the callback isn't really removed from the queue because it's an ongoing event handler, not a single use handler likesetTimeout
(ongoing, and single-use here are my words, don't really know the official names for these) – Correctitude