Node事件驱动模型

Event driven(事件驱动)

Node采用的是事件驱动的方式,通过事件驱动的方式处理请求时无需为每一个请求创建额外的线程。在事件驱动模型中,每一个I/O操作都会被添加到事件队列中,主线程循环地处理队列上的工作任务,当执行过程中遇到阻塞(读取文件、查询数据库)时,线程不会停下来等待结果,而是留下一个处理结果的回调函数,转而继续执行队列中的下一个任务。这个传递到队列中的回调函数在阻塞任务运行结束后才被线程调用。

事件驱动

主线程的代码执行完毕就会从事件队列中读取事件,如果有就取出事件并执行相关的回调函数。事件队列事件全部执行完毕,node应用就会终止。Node对于阻塞I/O的处理在幕后使用线程池来确保工作的执行。Node从线程池中取得一个线程来执行复杂任务,而不占用主循环线程。这样就防止阻塞I/O占用空闲资源。当阻塞任务执行完毕通过添加到事件队列中的回调函数来处理接下来的工作。

线程池

Node基于事件的工作调度能很自然地将主要的调度工作限制到了一个线程,应用能很高效地处理多任务。程序每一时刻也只需管理一个工作中的任务。当必须处理阻塞I/O时,通过将这个部分的I/O控制权交给线程池中的线程,能最小地影响到应用处理事件,快速地反应web请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const fs = require("fs");
console.time("timer");
//判断是否存在a.txt文件
fs.stat("./a.txt",(err,stats) => {
if(err){
console.log("文件不存在");
//不存在的话,我们就创建
fs.writeFile("./a.txt",new Date(),(err) => {
if(err) throw err;
console.log("文件创建成功")
})
}else {
//如果存在的话,先删除
fs.unlink("./a.txt",(err) => {
if(err) throw err;
//创建
fs.writeFile("./a.txt",new Date(),(err) => {
if(err) throw err;
console.log("文件删除后创建成功");
})
})
}
});
console.timeEnd("timer");
1
2
3
4
5
6
7
$ node 01-event-driven.js
timer: 0.444ms
文件不存在
文件创建成功
$ node 01-event-driven.js
timer: 0.427ms
文件删除后创建成功

我们来看一下具体过程


本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid.github.io/Node/node-learning-notes-01.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!