Node.js 事件循环是 Node.js 运行时环境中的一个核心机制,用于管理异步操作和回调函数的执行顺序。它基于事件驱动模型,通过事件循环来处理和派发事件,以及执行相应的回调函数。
Node.js 事件循环的主要步骤包括:
对于每个事件的处理过程,Node.js 会执行以下操作:
总结:
Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为 webserver 一直接受请求而不等待任何读写操作。(这也称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。
Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下实例:
// 引入 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("程序执行完毕。");
执行结果:
$ node test_event.js
连接成功。
数据接收成功。
程序执行完毕。
当你运行一个 Node 应用程序时,它会经历以下步骤:
const http = require('http');
function onRequest(request, response) {
response.writeHead(200, { 'Content-Type': 'text/plain' });
response.write('Hello, World!');
response.end();
}
const server = http.createServer(onRequest);
server.listen(3000);
console.log('Server is running on port 3000');
在这个例子中,我们通过 http 模块创建了一个 HTTP 服务器,并将其绑定到 3000 端口。当服务器收到请求时,会调用 onRequest 函数处理请求并返回响应。
const fs = require('fs');
fs.readFile('data.txt', 'utf8', function (error, data) {
if (error) {
console.error('Error:', error);
return;
}
console.log('File content:', data);
});
在这个例子中,我们使用 fs 模块异步地读取名为 data.txt 的文件。读取操作完成后,调用回调函数来处理读取的文件内容。
const http = require('http');
const fs = require('fs');
function onRequest(request, response) {
fs.readFile('data.txt', 'utf8', function (error, data) {
if (error) {
response.writeHead(500, { 'Content-Type': 'text/plain' });
response.write('Internal Server Error');
response.end();
return;
}
response.writeHead(200, { 'Content-Type': 'text/plain' });
response.write(data);
response.end();
});
}
const server = http.createServer(onRequest);
server.listen(3000);
console.log('Server is running on port 3000');
现在,当收到 HTTP 请求时,服务器会异步地读取文件,并在读取完成后发送文件内容作为响应。