I’d like to know how the following pieces of a javascript environment interconnect as a system.
We can limit this to a browser environment since node has been covered in another article (here)
Javascript is single threaded and therefore only has one callstack.
Javascript environments provide only a few functions that are truly asynchronous. These may include setTimeout(), setInterval(), and I/O function(s).
console.log(‘Sync code started…’); setTimeout(function asyncLog() { console.log(‘Async function has completed’) }, 2000); console.log(‘Sync code finished…')
( Please correct steps if I’m wrong )
These don’t need to be answered one by one if someone could produce an overview of the steps of how and where async functions (such as setTimeout) go from the time they first hit the callstack to when they are called back to the callstack.
Microtask Queue gets the callback functions coming through Promises and Mutation Observer. Callback Queue has lesser priority than Microtask Queue of fetching the callback functions to Event Loop. Microtask Queue has higher priority than Callback Queue of fetching the callback functions to Event Loop.
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.
The language itself is single-threaded, but the browser APIs act as separate threads. The event loop facilitates this process; it constantly checks whether or not the call stack is empty. If it is empty, new functions are added from the event queue. If it is not, then the current function call is processed.
The Event Loop has one simple job — to monitor the Call Stack and the Callback Queue. If the Call Stack is empty, the Event Loop will take the first event from the queue and will push it to the Call Stack, which effectively runs it. Such an iteration is called a tick in the Event Loop.
Your understanding and your example seem to be basically correct. Now, to your questions:
On step 3, who produces this new thread? Is it the browser?
Yes. It is basically the thing that supplies the implementation for those "truly asynchronous" functions. IIRC, setTimeout
is implemented in JS engines directly, while networking IO would be definitely the browser's responsibility - but it doesn't really matter who creates them. In the end, in your "browser environment" it's always some part of the browser.
This new thread is being blocked correct?
Yes. No. It depends on the work that needs to be done, i.e. which async function you called. Some may require spinning of a new thread, but for simple timeouts I'm pretty sure that a non-blocking system call is used.
What happens if you have a loop that creates 1000 setTimeouts. Are 1000 ‘threads’ created?
Possible. Unlikely, though. I'd assume for those async actions that really require their own thread, a thread pool is used, and requests are queued. The size of this pool might be hidden in the bowels of your browser's configuration.
Is there a limit to how many threads can be spawned at a time?
That would be controlled by the OS.
When new thread finishes executing, how does it end up on the queue? Who supplies the Event Queue?
Basically, the last action of each such thread is to put its result in the event queue.
Who supplies the Event Loop? Does the event loop poll the Event Queue?
I'd say that's an implementation detail, whether the loop polls the queue or the queue drives the loop iterations.
Is the javascript’s thread aware of an event loop? Or does the Event loop just push things onto the stack?
I'd say that the javascript runs in the event loop thread. The event loop just repeatedly pops events from the queue and executes their javascript.
How does the Event loop know when the stack is clear?
The event loop calls the javascript execution - so the stack is clear when the javascript returns.
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