Home  >  Article  >  Web Front-end  >  In-depth understanding of Node.js event loop and callback functions

In-depth understanding of Node.js event loop and callback functions

高洛峰
高洛峰Original
2016-12-08 10:26:531405browse

This article introduces the Node.js event loop and Node.js callback function in detail. I won’t go into too much nonsense. See below for details.

1. Node.js event loop

Node.js is a single-process, single-threaded application, but it 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. Basically all event mechanisms in Node.js 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.

1. Event-driven The program

Node.js uses an 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 head of the queue is reached, the result is returned to the user. This model is very efficient and scalable because the web server 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 trigger a callback function when an event is detected.

The entire event-driven process is implemented in this way, very simple. 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();
以下程序绑定事件处理程序:
// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);
我们可以通过程序触发事件:
// 触发事件
eventEmitter.emit('eventName');

2. Example

Create 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("程序执行完毕。");

2. Node.js callback function

Node.js The direct manifestation of asynchronous programming is callback. Asynchronous programming relies on callbacks, but it cannot be said that the program becomes asynchronous after using callbacks. The callback function will be called after completing the task. Node uses a large number of callback functions. All Node APIs support callback functions. For example, we can read a file while executing other commands. After the file reading is completed, we return the file content as a parameter of the callback function. This way there is no blocking or waiting for file I/O operations while executing code. This greatly improves the performance of Node.js and can handle a large number of concurrent requests.

1. Blocking code example

Create a file test.txt with the following content:

Hello World!
fs.readFileSync()
fs.readFile()

Create a test.js file with the following code:

console.log('-------程序开始执行--------'); 
// 引入fs模块
var fs = require("fs");
//同步读取文件
var data = fs.readFileSync('test.txt','utf-8');
console.log(data.toString());
console.log('-------程序执行结束--------');

The above code execution results are as follows:

2. Non-blocking code example

Create test.js file, the code is as follows:

console.log('-------程序开始执行--------'); 
// 引入fs模块
var fs = require("fs");
//异步读取文件
fs.readFile('test.txt','utf-8',function (err, data) {
  if (err) return console.error(err);
  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.

The execution results of the above code are as follows:
Next we delete the input.txt file, and the execution results are as follows:
In the above two examples, we understand the difference between blocking and non-blocking calls. The first instance finishes executing the program after the file has been read. In the second example, we do not need to wait for the file to be read, so that the next code can be executed at the same time as the file is read, which greatly improves the performance of the program. Therefore, blocking is executed in order, while non-blocking does not need to be in order, so if we need to process the parameters of the callback function, we need to write it in the callback function.

3. fs.readFileSync and fs.readFile

1. s.readFileSync

Syntax: fs.readFileSync(filename, [encoding])

Receive parameters:

filename: file path

options: option object , including encoding, encoding format, this item is optional.

Since Node.js only supports the following encodings: utf8, ucs2, ascii, binary, base64, hex, it does not support encodings such as Chinese GBK or GB2312, so if you want to read and write the Chinese content of files in GBK or GB2312 format, An additional module must be used: iconv-lite.

2. fs.readFile

Syntax: fs.readFile(filename, [encoding], [callback(err,data)])

Receive parameters:

filename: file path

options: option object, including encoding , encoding format, this item is optional.

callback: callback, passing 2 parameters: exception err and file content data


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn