Node.js 不是什么?
- Node.js 不是Web后端框架,不能与 Spring 和 Flask 相比
- Node.js 不是编程语言,不能与 Python 和 PHP 相比
Node.js 是什么?Wiki
-
Node.js 是一个平台
- 它组合多种技术
- 它让 JavaScript 也能调用系统接口,开发后端应用
-
Node.js 用到了哪些技术
V8 引擎、libuv、C/C++ 实现的 c-ares(DNS解析)、http-parser(HTTP 解析)、OpenSSL(HTTPS)、zlib(压缩) 等库。
如果对源码实现感兴趣,推荐查看:
Node.js 技术架构
Node.js 技术架构如图所示,下面简单介绍一下它们的作用
bindings
假如 C/C++ 实现了一个 xxx 库,很好用,JS 无法直接调用它。Node.js 用 C++ 对其进行了封装,使它符合某些要求。封装的文件叫 xxx_bindings.cpp,然后使用 Node.js 编译为 .node 文件(并不是唯一的方式,也有其他方法),然后 JS 可以直接 require 这个文件,binding 文件就是 JS 和 C/C++ 库中间的桥梁,而 Node.js 提供了很多 binding,所以加个 s,也就是 bindings
libuv
一个跨平台的异步 I/O 库,会根据系统自动选择合适的方案
用于 TCP / UDP / DNS / 文件等异步操作
I/O 是什么?
所有输入输出都属于I/O,例如文件读写、访问网络、发送接收文件等
V8
功能
- 将 JS 源码变成本地代码执行
- 维护调用栈,确保 JS 函数的执行顺序
- 内存管理
- 垃圾回收,重复利用无用的内存
- 实现 JS 的标准库
注意
- V8 不提供 DOM API
- V8 执行 JS 是单线程的
- 可以开启两个线程分别执行 JS
- V8 本身是多线程的
- V8 自带 event loop 但是 Node.js 基于 libuv 自己做了一个
简单说一下 Event Loop:
Event(事件)
计时器到期、文件可读、文件读取出错、socket有内容了、socket 关闭了,这些都是Event
Loop(循环)
事件是有优先级的,例如:
setTimeout(f1,100) fs.readFile('/1.txt',f2) server.on('close',f3)这上面的三个事件如果同时发生,肯定是会有一个执行优先级的规则(人为规定)的,而 Node.js会按照这个规则轮询事件,如 1->2->3->1->2->3
Event Loop
推荐阅读:Event Loop、计时器、nextTick-方应杭
操作系统触发事件,JS 处理事件,Event Loop 就是对事件处理顺序的管理
执行顺序
重点:
- timer检查定时器
- poll 轮询,检查系统事件
- check 检查 setImmediate 回调
- 其他阶段很少使用
大部分时间,Node.js 都停在 poll 轮询阶段。大部分事件也都在 poll 阶段被处理,如文件、网络请求。
setTimeout(f1,0) setImmediate(f2) // 上方代码大部分时间是 setImmediate 先执行 // 因为大部分时间 Node.js 停留在 poll 阶段 // 前往 timer 阶段需要先经过 check 阶段 // 会先执行 setImmediate 回调
总结
- 用 libuv 进行异步 I/O 操作
- 用 event loop 管理事件处理顺序
- 用 C/C++ 库高效处理 DNS/HTTP...
- 用 bindings 让 JS 能和 C/C++ 沟通
- 用 V8 运行 JS
- 用 Node.js 标准库简化 JS 代码
- 这就是 Node.js
Node.js API
Node.js API 是 Node.js 对外开放用来调用上述功能进行的应用接口,需要使用时可自行查看文档