1 Node.js是个啥
1.1 首先明确Node.js 不是什么
- 不是web框架。不能将Node.js与Flask或Spring进行对比
- 不是编程语言。Node.js并不是后端的JS,所以不能把Node.js与Python或PHP进行对比
1.2 然后,Node.js是什么
- 是一个平台。它将多种技术组合起来,让JS也能调用系统接口、开发后端应用
- Node.js用到的技术:V8引擎;libuv;C/C++实现的c-areas、http-parser、OpenSSL、zlib等库
1.3 Node.js技术架构
随着Node.js版本升级,其架构也在一直变化
推荐观看0.10版本的源代码,因为这一版本使用了很长一段时间,且源代码数量较最新版少很多
如果想了解更多,可以看一下github.com/yjhjstz/deep-into-node
1.3.1 什么是bindings
背景
- C/C++实现了一个http_parse 库,很高效
- 你想调用这个库,但是你只会写JS
- 直接调用肯定不成功,你需要一个中间桥梁
bindings
- Node.js用C++对http_parse进行封装,使它符合一些要求,封装的文件叫做http_parse_bindings.cpp
- 用Node.js提供的编译工具将其编译为.node文件*
- JS代码可以直接require这个.node文件
- 这样JS就能间接调用C++库,中间的桥梁就是binding
- 由于Node.js提供了很多binding,所以叫bindings
*编译成.node文件不是必须的,可以时其他任何可行的方式
JS与C++交互
*交互方式并不唯一
- JS调用C++代码:nodejs.cn/api/addons.…
- C++调用JS回调:nodejs.cn/api/addons.…
1.3.2 libuv
- libuv是一个跨平台的异步I/O库,会根据系统自动选择合适的方案
- libyv可以用于TCP/UDP/DNS/文件等的异步操作
1.3.3 V8
功能:
- 将JS源代码变成本地代码并执行
- 维护调用栈,确保JS函数的执行顺序
- 内存管理,为所有对象分配内存
- 垃圾回收,重复利用内存
- 实现JS的标准库
注意:
- V8不提供DOM API
- V8执行JS是单线程的
- 可以开启两个线程分别执行JS
- V8本身是包含多个线程的,例如垃圾回收就是单独线程
- V8自带event loop,但Node.js基于libuv自己做了一个
1.3.4 Event Loop
操作系统可以触发事件,JS可以处理事件。Event Loop就是对事件处理顺序的管理
Event Loop的顺序示意图:
重点阶段
- timers,检查计时器
- poll轮询,检查系统事件
- check检查setImmediate回调
- 其他阶段用的较少
注意
- 大部分时间,Node.js都停在poll轮询阶段
- 大部分时间都在poll阶段被处理,如文件、网络请求