In-depth understanding of Node event loop (EventLoop) mechanism
The main thread reads events from the "task queue". This process is cyclic, so the entire running mechanism is also called Event Loop. The following article will help you master the eventloop in Node.js. I hope it will be helpful to you!
Although js
can be executed in the browser and node
, their event loop mechanism is not the same. And there is a big difference.
Overview of the EventLoop mechanism
Before talking about the Node
event loop mechanism, let us first discuss two issues
Why should we learn the event loop mechanism?
Learning the event loop can allow developers to understand how JavaScript
operates.
What does the event loop mechanism do?
The event loop mechanism is used to manage when the callback function of the asynchronous API returns to the main thread for execution .
Node.js uses an asynchronous IO model. The synchronous API is executed in the main thread, the asynchronous API is executed in the thread maintained by the underlying C, and the callback function of the asynchronous API will also be executed in the main thread. [Recommended related tutorials: nodejs video tutorial, Programming teaching]
When a Javascript application is running, when can the callback functions of many asynchronous APIs return to the main thread? What about calls? This is what the event loop mechanism does, managing when the callback function of the asynchronous API returns to the main thread for execution.
The six stages of EventLoop
The event loop in Node
is divided into six stages.
There is a queue at each stage in the event loop to store the callback functions to be executed. The event loop mechanism will execute them in a first-in, first-out manner until the queue is null.
These six stages all store asynchronous callback functions, so it is still necessary to execute the main thread synchronization code first, and then poll these six stages after the synchronization code is executed.
Next, let’s take a detailed look at what is stored in these six stages
Timers
Timers
: Callback function (setlnterval, setTimeout) used to store timers.
Pendingcallbacks
Pendingcallbacks
: Execute callback functions related to the operating system, such as the callback function that monitors port operations when starting a server-side application. Called here.
idle, prepare
idle, prepare
: used internally by the system. (We programmers don’t need to worry about this)
Poll
Poll
: Stores the callback function queue for 1/O operations, such as file read and write operations callback function.
Special attention needs to be paid at this stage. If there are callback functions in the event queue, they will be executed until the queue is cleared. , otherwise the event loop will stay at this stage for a while to wait for a new callback function to enter.
But for this waiting is not certain, but depends on the following two conditions:
- If there is something to be executed in the setlmmediate queue (check phase) adjustment function. In this case there will be no waiting.
- There is a callback function to be executed in the timers queue, and there will be no waiting in this case. The event loop will move to the check phase, then to the Closingcallbacks phase, and finally from the timers phase to the next loop.
Check
Check
: Stores the callback function of setlmmediate.
Closingcallbacks
Closingcallbacks
: Execute callbacks related to closing events, such as callback functions for closing database connections, etc.
Macro tasks and micro tasks
Like js
in the browser, the asynchronous code in node
is also divided into They are macrotasks and microtasks, but the execution order between them is different.
Let’s take a look at the macro tasks and micro tasks in Node
Macro tasks
setlnterval
setimeout
setlmmediate
I/O
Microtasks
- ##Promise.then
- Promise.catch
- Promise.finally
- process.nextTick
node, for microtasks and macros What is the order of execution of tasks?
Execution sequence of microtasks and macrotasks
In node
, the callback function of the microtask is placed in the microtask queue, and the callback function of the macrotask is placed in the macro task queue.
Microtasks have higher priority than macrotasks. When there is an executable callback function in the microtask event queue, the event loop will pause and enter the next stage of the event loop after executing the callback function of the current stage, and will immediately enter the microtask's event queue to start executing the callback function. When the callback function in the microtask queue is executed, the event loop will enter the next segment and start executing the callback function.
There is another point we need to pay special attention to when it comes to microtasks. That is, although nextTick
is also a micro-task, its priority is higher than other micro-tasks. When executing a micro-task, only after all callback functions in nextlick
are executed. Other microtasks will start to be executed.
In general, when the main thread synchronization code is executed, the microtasks will be cleared first (if the microtasks continue to generate microtasks, they will be cleared again), and then go to the next event loop stage. And the execution of microtasks is interspersed among the six stages of the event loop. That is, before each event loop enters the next stage, it will determine whether the microtask queue is empty. If it is empty, it will enter the next stage. Otherwise, the microtasks will be cleared first. queue.
Let’s use code practice to verify what we said above.
Code example
Execute synchronization first and then asynchronously
After the Node
application starts , will not enter the event loop immediately, but will execute the synchronous code first, starting from top to bottom. The synchronous API will be executed immediately, and the asynchronous API will be handed over to the thread maintained by C for execution. The callback function of the asynchronous API will be registered to the corresponding event queue. middle. When all synchronization codes are executed, the event loop will be entered.
console.log("start"); setTimeout(() => { console.log("setTimeout 1"); }); setTimeout(() => { console.log("setTimeout 2"); }); console.log("end");
Let’s look at the execution results
You can see that the synchronous code is executed first, and then the event loop is entered to execute the asynchronous code. In The timers
stage executes two setTimeout
callbacks.
Will setTimeout be executed before setImmediate?
We know that setTimeout
is executed in the timers
stage, setImmediate
is executed in the check
phase. And the event loop starts from the timers
phase. Therefore, setTimeout
will be executed first and then setImmediate
.
Is the above analysis correct?
Let’s look at the example
console.log("start"); setTimeout(() => { console.log("setTimeout"); }); setImmediate(() => { console.log("setImmediate"); }); const sleep = (delay) => { const startTime = +new Date(); while (+new Date() - startTime < delay) { continue; } }; sleep(2000); console.log("end");
Execute the above code, the output is as follows
Execute firstsetTimeout
then execute setImmediate
Next let’s transform the above code, remove the delayer, and see what will be output
setTimeout(() => { console.log("setTimeout"); }); setImmediate(() => { console.log("setImmediate"); });
We ran it seven times and you can see it Twice, setImmediate
was run first. What happened? Isn’t it first the timers
stage and then the check
stage? How could it change?
In fact, it depends on whether the asynchronous callback is fully ready when entering the event loop. For the initial example, because there is a delay of 2000 milliseconds, the setTimeout
callback must be ready when entering the event loop. So the order of execution will not change. But for this example, because the main thread has no synchronization code to execute, it enters the event loop at the beginning. However, when entering the event loop, the callback of setTimeout
is not necessarily fully prepared, so it will There is a callback function that first executes the setImmediate
in the check
stage, and then executes the setTimeout
callback in the timers
stage of the next event loop.
Under what circumstances will the setImmediate
callback function take precedence over the setTimeout
callback for the same delay time?
It's actually very simple, just put these two in the Pendingcallbacks, idle, prepare, poll
between the timers
stage and the check
stage Any one of the stages will do. Because after these stages are executed, they will definitely go to the check
stage and then the timers
stage.
We take the poll
stage as an example and write these two in the IO operation.
const fs = require("fs"); fs.readFile("./fstest.js", "utf8", (err, data) => { setTimeout(() => { console.log("setTimeout"); }); setImmediate(() => { console.log("setImmediate"); }); });
We also execute it seven times. You can see that setImmediate
is executed first every time.
So in general, with the same delay time, setTimeout
is not 100% executed before setImmediate
.
先微任务再宏任务
主线程同步代码执行完毕后,会先执行微任务再执行宏任务。
我们来看下面的例子
console.log("start"); setTimeout(() => { console.log("setTimeout"); }); setImmediate(() => { console.log("setImmediate"); }); Promise.resolve().then(() => { console.log("Promise.resolve"); }); console.log("end");
我们运行一下看结果,可以看到它是先执行了微任务然后再执行宏任务
nextTick优于其它微任务
在微任务中nextTick
的优先级是最高的。
我们来看下面的例子
console.log("start"); setTimeout(() => { console.log("setTimeout"); }); setImmediate(() => { console.log("setImmediate"); }); Promise.resolve().then(() => { console.log("Promise.resolve"); }); process.nextTick(() => { console.log("process.nextTick"); }); console.log("end");
我们运行上面的代码,可以看到就算nextTick
定义在resolve
后面,它也是先执行的。
微任务穿插在各个阶段间执行
怎么理解这个穿插呢?其实就是在事件循环的六个阶段每个阶段执行完后会清空微任务队列。
我们来看例子,我们建立了timers、check、poll
三个阶段,并且每个阶段都产生了微任务。
// timers阶段 setTimeout(() => { console.log("setTimeout"); Promise.resolve().then(() => { console.log("setTimeout Promise.resolve"); }); }); // check阶段 setImmediate(() => { console.log("setImmediate"); Promise.resolve().then(() => { console.log("setImmediate Promise.resolve"); }); }); // 微任务 Promise.resolve().then(() => { console.log("Promise.resolve"); }); // 微任务 process.nextTick(() => { console.log("process.nextTick"); Promise.resolve().then(() => { console.log("nextTick Promise.resolve"); }); });
我们来执行上面的代码
可以看到,先执行微任务,再执行宏任务。先process.nextTick -> Promise.resolve
。并且如果微任务继续产生微任务则会再次清空,所以就又输出了nextTick Promise.resolve
。
接下来到timer
阶段,输出setTimeout
,并且产生了一个微任务,再进入到下个阶段前需要清空微任务队列,所以继续输出setTimeout Promise.resolve
。
接下来到check
阶段,输出setImmediate
,并且产生了一个微任务,再进入到下个阶段前需要清空微任务队列,所以继续输出setImmediate Promise.resolve
。
这也就印证了微任务会穿插在各个阶段之间运行。
总结
所以对于Node
中的事件循环你只需要背好一以下几点就可以了
当主线程同步代码执行完毕后才会进入事件循环
事件循环总共分六个阶段,并且每个阶段都包括哪些回调需要记清楚。
事件循环中会先执行微任务再执行宏任务。
微任务会穿插在这六个阶段之间执行,每进入到下个阶段前会清空当前的微任务队列。
微任务中
process.nextTick
的优先级最高,会优先执行。
更多node相关知识,请访问:nodejs 教程!
The above is the detailed content of In-depth understanding of Node event loop (EventLoop) mechanism. For more information, please follow other related articles on the PHP Chinese website!

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft