Processes and threads
Single threading in JavaScript means that there is only one thread in a process that executes code
The difference between a process and a thread
- Processes are the smallest unit of CPU resource allocation; Threads are the smallest unit of CPU scheduling
- A process consists of one or more threads, which are different execution paths of code in a process
- The memory space of a process can be shared with the threads in it
Processes are like factories, with lots of resources to process; Threads are similar to workers, each using resources to complete a product
Multi-process is like when you’re in front of a computer and you’re typing code and you’re listening to music at the same time. That’s multi-process
Multithreading A program can run multiple threads simultaneously to perform different tasks
The reason JavaScript is single threaded is that JS can be used to manipulate the DOM, and if it’s multi-threaded, one thread will modify the DOM-a, and another thread will delete the DOM-a, so the browser doesn’t know which one to use.
Execution stack and task queue
JavaScript divides all tasks into synchronous and asynchronous tasks
The execution stack is equivalent to a stack structure for storing function calls, following the principle of first in, last out
- All synchronization tasks are executed on the main thread, forming an execution stack
- In addition to the main thread, there are task queues. When an asynchronous task has a run result, one is placed in the task queue
- Once all synchronization tasks in the execution stack are completed, the system reads the task queue
- The main thread repeats 3
Asynchronous tasks are divided into:
- Macro tasks: Script (overall code), setTimeout, setInterval, setImmediate (Nodejs), I/O, UI rendering
- NextTick (Nodejs), Promises, Object.observe, MutationObserver
Note: setTimeout(fn,t) really means that, after t seconds, FN is put into the task queue, and when the main thread finishes executing the task on the execution stack, FN is removed from the task queue to execute. So setTimeout the second parameter means fn will be executed at least t seconds later
Event loop
The main thread reads events from the task queue in a loop called an EventLoop.
Running mechanism of JavaScript in browser:
- When the JavaScript code runs, the execution stack is empty, the microtask queue is empty, and the macro task queue has one and only one script.
- Global context (script tags) are pushed onto the execution stack, synchronizing code execution, and generating new microtasks and macro tasks
- When the synchronization task in the global context (script tag) completes, the queue of microtasks generated by this macro task is emptied
- Perform render operations to update the interface
- Check whether Web worker tasks exist and process them if so
- Then go to the macro task queue to process the next macro task, repeating 3-6 (Event Loop)
The Node in the Event Loop
Node.js uses V8 as the PARSING engine of JS, and libuv designed by myself is used for I/O processing. Libuv is a cross-platform abstraction layer based on event-driven, which encapsulates some underlying features of different operating systems and provides a unified API externally. The event loop mechanism is also implemented inside it
Node operation mechanism
- The V8 engine parses JavaScript scripts, parses the code, and calls the Node API (libuv library)
- The Libuv library assigns different tasks to different threads, forming an Event Loop that asynchronously returns the results of the tasks to the V8 engine
Six stages
External input data –> Polling stage –> Check stage –> Close callback stage –> Timer detection stage –>I/O callback stage –> IDLE stage Prepare)–> Polling stage…
- The poll phase gets new I/O events, where node blocks under appropriate conditions
- The Check phase performs the setImmediate() callback
- The Closecallbacks phase performs the socket’s close event callback
- Timers Stage This stage performs the callback of timer (setTimeout, setInterval)
- The I/O Callbacks phase handles some of the few UNexecuted I/O callbacks from the previous cycle
- Idle, used only in the node during the prepare phase
Note: Process. nextTick is separate from the Event Loop, it has its own queue, and when each stage is complete, if there is a nextTick queue, it empties all callback functions in the queue
There are also two types of asynchronous queues in the Node side event loop: macro task queue and micro task queue
- Common macro-tasks include setTimeout, setInterval, setImmediate, Script, I/O, etc
- Common micro-tasks include process.nexttick, New Promise().then(callback), and so on
The Event Loop of Node is different from that of the browser
- In the browser environment, the microTask queue is executed after each MacroTask has been executed
- In Node, microTasks are executed between phases of the event cycle, i.e. tasks in the MicroTask queue are executed after each phase is completed
setTimeout(() = >{
console.log('timer1')
Promise.resolve().then(function() {
console.log('promise1')})},0)
setTimeout(() = >{
console.log('timer2')
Promise.resolve().then(function() {
console.log('promise2')})},0)
Copy the code
reference
- What’s the difference between browser and Node Event loops
- This time, thoroughly understand the JavaScript execution mechanism
- More on the Event Loop
- Thoroughly understand browser event-loop