Node.js开发指南——第3章安装Node.js快速入门(二) 异步式I/O
Node.js最大的特点是异步式I/O(或者非阻塞I/O).
同步式I/O(阻塞式)
|
异步式I/O(非阻塞式)
|
利用多线程提供吞吐量
通过事件片分割和线程调度利用多核CPU
需要由操作系统调度多线程使用多核CPU
难以充分利用CPU资源
内存轨迹大,数据局部性弱
符合线性的编程思维
|
单线程即可实现高吞吐量
通过功能划分利用多核CPU
可以将单进程绑定到单核CPU
可以充分利用CPU资源
内存轨迹小。数据局部性强
不符合传统编程思维
|
同步式I/O: 线程在执行中如果遇到磁盘读写或网络通信(统称为I/O操作),通常要耗费较长的时间,这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为阻塞。当I/O操作完毕,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种I/O模式就是通常的同步式I/O(Synchronous I/O).
异步式I/O: 当线程遇到I/O操作时,不会以阻塞的方式等待I/O操作的完成或数据的返回,而只是将I/O请求发送到操作系统,继续执行下一条语句。当操作系统完成I/O操作时,以事件的形式通知执行I/O操作的线程,线程会在特定时候处理这个事件。为了处理异步I/O,线程必须有事件循环,不断地检查有没有未处理的事件,依次处理。
单线程事件驱动的异步式I/O比传统的多线程阻塞式I/O究竟好在哪里呢?异步式I/O就是少了多线程的开销。
异步式编程的缺点在于不符合人们一般的程序设计思维。不过可喜的是现在已经有了不少专门解决异步式编程问题的库(如async)
下面是关于Node.js如何用异步的方式读取一个文件的例子。
先新建一个文本file.txt,因为我这里的内容是中文,这里就有个注意的地方。保存的txt默认编码是ANSI的,Node.js是读不出中文的,只认utf8编码。如果不是中文内容,不用改编码,直接保存就行。
所以按我的方法来改编码:打开记事本新建一个空白的文本文档,不输入任何文字,然后保存此文档,在“另存为”对话框中将编码
由默认的 ANSI 修改为 UTF-8,接着为文件取名,在此将新文档命名为 file.txt。
然后写readfile.js
var fs = require('fs'); fs.readFile('file.txt','utf-8',function(err,data){ if(err){ console.error(err); }else{ console.log(data); } }); console.log('end.');
运行结果如下:
从结果看出: end先被输出。这就是异步式I/O,通过回调函数来实现的。fs.readFile第一个参数是文件名,第二个参数是编码方式,第三个是一个函数,我们将这个函数为回调函数。fs.readFile调用时所做的工作只是将异步式I/O请求发送给操作系统,然后立即返回并执行后面的语句,执行完成以后进入事件循环监听事件。当fs接收到I/O请求完成的事件时,事件循环会主动调用回调函数以完成后续工作。因此我们会先看到end.再看到txt文件内容。
Node.js也提供了同步读取文件的API:
//readfilesync.js var fs = require('fs'); var data = fs.readFileSync('file.txt','utf-8'); console.log(data); console.log('end');
结果如下:
分类:
读书笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探