node事件循环机制

Nodejs的核心机制就是事件驱动和异步IO。但是nodejs是单进程单线程的,也就是一次只能做一件事,如何实现高并发呢?

Nodejs在主线程中维护了一个事件循环队列,当收到请求时,就将请求放入事件循环队列,然后继续接收请求。当主线程空闲时(没有新请求进入),就会检查事件循环队列中是否有事件需要处理。要处理的事件分两种,如果是非I/O任务,则主线程自己处理(同步处理,占用主进程);如果是I/O任务,则会从线程池中拿出一个线程来处理,同时指定回调函数,然后继续循环事件队列(异步处理)。

当线程中的I/O任务处理完成了,就会调用指定的回调函数,将处理完成的任务放入事件循环队列的尾部。当主线程再次循环到该事件,直接将处理结果直接返回给上层。这个过程就是事件循环Event Loop,以下是事件循环的原理图:

event loop

该事件循环包含几个部分,应用层、V8引擎层、Node API层、Libuv层。

每一层的作用如下:

应用层:即JavaScript交互层,常用的就是nodejs模块,如http,fs等;

V8引擎层:JavaScript解析器,同时和下层Nodejs API交互;

Node API层:为上层提供系统调用,一般使用C语言来实现的,同时与操作系统交互;

Libuv层:跨平台的底层库,封装了文件操作、网络操作等基本操作,是nodejs实现异步的核心;

PS: Nodejs并不是真正的单进程单线程,只是说Nodejs运行在单线程之内,底层实现还是多线程的。

 

### Node.js 事件循环机制详解 #### 事件循环的重要性 Node.js 的事件循环机制是其处理非阻塞 I/O 操作的核心,这使得单线程能够高效处理多个并发请求。由于采用非阻塞 I/O 和事件驱动模型,即使面对大量并发的 I/O 请求,也不会导致线程阻塞,从而保证了高效的性能[^1]。 #### 事件循环的工作原理 Node.js 中几乎每一个 API 都支持回调函数,基本所有的事件机制都是用设计模式中的观察者模式实现。单线程类似于进入一个 `while (true)` 的事件循环,直到没有事件观察者退出为止。每个异步事件都会生成一个事件观察者;一旦有事件发生,则会调用对应的回调函数[^4]。 #### 事件循环的具体阶段 事件循环分为几个不同的阶段,在每一趟循环过程中依次执行各个阶段的任务队列: - **Timers**: 执行已到时间的定时器回调。 - **Pending callback**: 执行一些系统操作的回调,比如 TCP 错误。 - **Idle, prepare**: 内部使用,通常不涉及用户代码。 - **Poll**: 获取新的 I/O 事件;执行与 I/O 相关的回调(除了关闭回调、定时器回调和其他少数例外)。适当条件下,节点将继续在此阶段轮询等待更多数据。 - **Check**: 执行 `setImmediate()` 回调。 - **Close callbacks**: 执行某些类型的关闭回调,例如 socket.on('close', ...)。 ```javascript // 定义不同类型的回调以展示各阶段的行为 setTimeout(() => { console.log('Timer1 fired'); }, 0); const fs = require('fs'); fs.readFile(__filename, () => { console.log('File read'); }); Promise.resolve().then(() => { console.log('Promise fulfilled'); }); ``` 上述代码片段展示了如何定义不同类型的时间点触发特定行为,帮助理解事件循环的不同部分是如何工作的[^2]。 #### 实现细节 V8 引擎提供了异步执行回调接口,允许 Node.js 处理大量的并发连接。尽管 Node.js 是单进程单线程的应用程序,但由于这种架构特性,依然能保持非常高的性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值