异步I/O为什么这么重要?它是 Node.js 的“杀手级应用”,正是这一点使它成功了
异步I/O是什么
- I/O:input/output,既指文件的读取,又指发送网络请求(相当于读取远程计算机资源了)
- 异步I/O:先发送I/O相应指令,之后接着执行后续程序,等读取文件或者网络资源完成时,再进行处理
const fs = require ('fs');
fs.readFile(fpath, 'utf8', (err, data) => {
console.log('读取文件完成')
});
console.log('发起读取文件');
// 发起读取文件
// 读取文件完成
为什么要异步I/O
-
用户体验
为了让用户拥有流畅的体验,在处理前端发来的网络请求时,Node服务器必须尽快执行完代码,返回给前端数据。其中I/O操作又非常耗时。- 如果串行读取多个文件,则总耗时为各个资源耗时总和:M+N
- 若并行读取多个,则总耗时为各资源耗时中最大值:max( M, N )
-
资源分配
- 单线程串行:性能差,I/O阻塞CPU计算,资源不能很好利用
- 多线程并行:创建线程和执行上下文切换开销大
Node.js = 单线程 + 异步I/O + 子进程
异步I/O实现
JavaScript运行在主线程中,将I/O交给别的线程去做,当I/O线程读取文件时,主线程可以处理其他工作。当I/O线程读取完成后,将数据返回给主线程。
我们常说Node是单线程的,主要是指JavaScript执行在单个线程中。在Node中,无论是*nix还是Windows平台,内部完成另有线程池。
事件循环
事件循环是Node自身的执行模型,也是异步I/O实现的核心
Node中的事件循环参考
JavaScript中事件循环和Nodejs中事件循环
彻底弄懂 NodeJs 事件循环-比官方更加详细
这两篇文章都提到了6个阶段,个人觉得看过了解就可以,没必要详细记忆。