Node.js event loop


Node.js event loop

Node.js is a single-process, single-threaded application, but supports concurrency through events and callbacks, so its performance is very high.

Every API in Node.js is asynchronous and runs as a separate thread, uses asynchronous function calls, and handles concurrency.

Node.js Basically all event mechanisms are implemented using the observer pattern in the design pattern.

Node.js single thread is similar to entering a while(true) event loop until no event observer exits. Each asynchronous event generates an event observer. If an event occurs, the callback function is called.


Event-driven program

Node.js uses the event-driven model. When the web server receives a request, it closes it and processes it, and then serves the next web request.

When the request is completed, it is put back into the processing queue, and when the beginning of the queue is reached, the result is returned to the user.

This model is very efficient and scalable because the webserver always accepts requests without waiting for any read or write operations. (This is also called non-blocking IO or event-driven IO)

In the event-driven model, a main loop is generated to listen for events, and a callback function is triggered when an event is detected.


The entire event-driven process is implemented in this way, very concisely. Somewhat similar to the observer pattern, the event is equivalent to a subject (Subject), and all handler functions registered to this event are equivalent to observers (Observer).

Node.js has multiple built-in events. We can bind and listen to events by introducing the events module and instantiating the EventEmitter class, as shown in the following example:

// 引入 events 模块var events = require('events');// 创建 eventEmitter 对象var eventEmitter = new events.EventEmitter();

The following program binds Event handler:

// 绑定事件及事件的处理程序eventEmitter.on('eventName', eventHandler);

We can trigger events through the program:

// 触发事件eventEmitter.emit('eventName');

Instance

Create the main.js file, the code is as follows:
// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

// 创建事件处理程序
var connectHandler = function connected() {
   console.log('连接成功。');
  
   // 触发 data_received 事件 
   eventEmitter.emit('data_received');
}

// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
 
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
   console.log('数据接收成功。');
});

// 触发 connection 事件 
eventEmitter.emit('connection');

console.log("程序执行完毕。");

Next let us execute the above Code:

$ node main.js
连接成功。
数据接收成功。
程序执行完毕。

How does the Node application work?

In Node applications, functions that perform asynchronous operations take the callback function as the last parameter. The callback function receives the error object as the first parameter.

Next let us re-look at the previous example and create an input.txt with the following file content:

菜鸟教程官网地址:www.runoob.com

Create the main.js file with the following code:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {
   if (err){
      console.log(err.stack);
      return;
   }
   console.log(data.toString());
});
console.log("程序执行完毕");

In the above program, fs.readFile() is an asynchronous function used to read files. If an error occurs while reading the file, the error err object will output error information.

If no error occurs, readFile skips the output of the err object, and the file content is output through the callback function.

Execute the above code, the execution result is as follows:

程序执行完毕
php中文网官网地址:www.php.cn

Next we delete the input.txt file, the execution result is as follows:

程序执行完毕
Error: ENOENT, open 'input.txt'

Because the file input.txt does not exist , so an error message is output.