Detailed explanation of event-driven programming in Node.js_node.js
In the traditional programming model, I/O operations are like an ordinary local function call: the program is blocked before the function is executed and cannot continue to run. Blocking I/O originated from the earlier time slice model. Under this model, each process is like an independent person. The purpose is to distinguish each person, and each person can usually only do one thing at the same time and must wait. Only when you finish the previous thing can you decide what to do next. But this "one user, one process" model that is widely used in computer networks and the Internet has poor scalability. When managing multiple processes, a lot of memory will be consumed, and context switching will also occupy a lot of resources. These are a huge burden on the operating system, and as the number of processes increases, system performance will decline sharply.
Multi-threading is an alternative. A thread is a lightweight process that shares memory with other threads in the same process. It is more like an extension of the traditional model and is used to execute multiple threads concurrently. When a thread While waiting for an I/O operation, other threads can take over the CPU. When the I/O operation is completed, the previously waiting thread will be awakened. That is, a running thread can be interrupted and then resumed later. In addition, under some systems threads can run in parallel on different cores of a multi-core CPU.
Programmers do not know when the thread will run at a specific time. They must be very careful to handle concurrent access to shared memory. Therefore, they must use some synchronization primitives to synchronize access to a certain data structure, such as using locks or semaphores. Use this to force threads to execute in specific behaviors and plans. Applications that rely heavily on shared state between threads are prone to strange problems that are highly random and difficult to find.
Another way is to use multi-thread collaboration. You are responsible for explicitly releasing the CPU and giving the CPU time to other threads. Because you personally control the execution plan of the thread, you reduce the need for synchronization. requirements, but it also increases the complexity of the program and the chance of errors, and does not avoid the problems of multi-threading.
What is event-driven programming
Event-driven programming (Evnet-driven programming) is a programming style in which events determine the execution flow of the program. Events are processed by event handlers or event callbacks. Event callbacks are the current A function that is called when a specific event occurs, such as the database returning query results or the user clicking a button.
Recall that in the traditional blocking I/O programming model, a database query might look like this:
result = query('SELECT * FROM posts WHERE id = 1');
do_something_with(result);
The above query function will keep the current thread or process in a waiting state until the underlying database completes the query operation and returns.
In an event-driven model, this query would look like this:
query_finished = function(result) {
do_something_with(result);
}
query('SELECT * FROM posts WHERE id = 1', query_finished);
First you define a function called query_finished, which contains what to do after the query is completed. Then pass this function as a parameter to the query function. When the query is executed, query_finished will be called instead of just returning the query results.
When the event you are interested in occurs, the function you define will be called instead of simply returning the result value. This programming model is called event-driven programming or asynchronous programming. This is one of the most obvious features of Node. This programming model means that the current process will not be blocked when performing I/O operations. Therefore, multiple I/O operations can be executed in parallel. When the operation is completed, the corresponding callback function will will be called.
The bottom layer of event-driven programming relies on the event loop. The event loop is basically a structure that continuously calls two functions: event detection and event processor triggering. In each loop, the event loop mechanism needs to detect which events have occurred. When the event occurs, it finds the corresponding callback function and calls it.
The event loop is just a thread running within the process. When an event occurs, the event handler can run alone and will not be interrupted, that is:
1. At most one event callback function can be run at a specific moment
2. Any event handler will not be interrupted while running
With this, developers can no longer worry about thread synchronization and concurrent modification of shared memory.
A well-known secret:
People in the systems programming community have known for a long time that event-driven programming is the best way to create high-concurrency services because it doesn’t have to save a lot of context, so it saves a lot of memory, it doesn’t have so many context switches, and it saves a lot of execution. time.
Slowly, this concept has penetrated into other platforms and communities, and some famous event loop implementations have emerged, such as Ruby's Event machine, Perl's AnyEvnet, and Python's Twisted. In addition to these, there are many other implementations and language.
To develop with these frameworks, you need to learn specific knowledge related to the framework and framework-specific class libraries. For example, when using Event Machine, in order to enjoy the benefits of non-blocking, you have to avoid using synchronization class libraries and can only use Asynchronous class library for Event Machine. If you use any blocking libraries (such as most of Ruby's standard libraries), your server loses optimal scalability because the event loop will still be constantly blocked, occasionally preventing the processing of I/O events. .
Node was originally designed as a non-blocking I/O server platform, so in general, you should expect all code running on it to be non-blocking. Because JavaScript is very small and it does not enforce any I/O model (because it does not have a standard I/O library), Node is built in a very pure environment without any legacy issues.
How Node and JavaScript simplify asynchronous applications
Ryan Dahl, the author of Node, initially used C to develop this project, but found that maintaining the context of function calls was too complicated, resulting in high code complexity. Then he switched to Lua, but Lua already has several blocking I/O libraries. Mixing blocking and non-blocking may confuse developers and prevent many people from building scalable applications, so Lua was also Dahl abandoned. Finally, he turned to JavaScript. Closures and first-level object functions in JavaScript made JavaScript very suitable for event-driven programming. The magic of JavaScript is one of the main reasons why Node is so popular.
What is a closure
A closure can be understood as a special function, but it can inherit and access variables in the scope in which it is defined. When you pass a callback function as a parameter to another function, it will be called later. The magic is that when the callback function is called later, it actually remembers the context in which it is defined and the parent context. variables in it, and they can be accessed normally. This powerful feature is at the core of Node's success.
The following example shows how JavaScript closures work in a web browser. If you want to listen to the stand-alone event of a button, you can do this:
var clickCount = 0;
document.getElementById('myButton').onclick = function() {
clickCount = 1;
alert("clicked " clickCount " times.");
};
This is how it works when using jQuery:
var clickCount = 0;
$('button#mybutton').click(function() {
clickedCount ;
alert('Clicked ' clickCount ' times.');
});
In JavaScript, functions are first-class objects, which means you can pass functions as parameters to other functions. In the two examples above, the former assigns a function to another function, and the latter passes the function as a parameter to another function. The handler function (callback function) of the click event can access every variable under the code block where the function is defined. , in this case, it has access to the clickCount variable defined within its parent closure.
The clickCount variable is in the global scope (the outermost scope in JavaScript). It saves the number of times the user clicks the button. It is usually a bad habit to store variables in the global scope because it can easily conflict with other code. , you should place variables in the local scope where they are used. Most of the time, just wrapping the code in a function is equivalent to creating an additional closure, so that you can easily avoid polluting the global environment, like this:
(function() {
var clickCount = 0;
$('button#mybutton').click(function() {
clickCount ;
alert('Clicked ' clickCount ' times.');
}());
Note: The seventh line of the above code defines a function and calls it immediately. This is a common design pattern in JavaScript: creating a new scope by creating a function.
How closures help asynchronous programming
In the event-driven programming model, first write the code that will be run after the event occurs, then put the code into a function, and finally pass the function as a parameter to the caller, which will later be called by the caller function.In JavaScript, a function is not an isolated definition. It will also remember the context of the scope in which it is declared. This mechanism allows JavaScript functions to access the context where the function is defined and the parent context. all variables.
When you pass a callback function as a parameter to the caller, this function will be called at a later time. Even if the scope in which the callback function is defined has ended, when the callback function is called, it can still access all variables in the ended scope and its parent scope. Like the last example, the callback function is called inside jQuery's click(), but it can still access the clickCount variable.
The magic of closures was shown earlier. Passing state variables to a function allows you to perform event-driven programming without maintaining state. JavaScript's closure mechanism will help you maintain them.
Summary
Event-driven programming is a programming model that determines the program execution flow through event triggering. Programmers register callback functions (often called event handlers) for the events they are interested in, and the system then calls the registered event handler when the event occurs. This programming model has many advantages that the traditional blocking programming model does not have. In the past, to achieve similar features, you had to use multi-process/multi-threading.JavaScript is a powerful language because its function and closure properties of first-type objects make it well-suited for event-driven programming.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

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.


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

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Atom editor mac version download
The most popular open source editor

Dreamweaver CS6
Visual web development tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Chinese version
Chinese version, very easy to use

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.