Node.js 初识
Node.js不是什么
不是web框架
- Node.js并不是web后端框架
- 所有不能把Node.js与Flask或Spring对比
不是编程语言
- Node.js并不是后端的JS
- 所以并不能将Node.js 与 Python 或 PHP对比
Node.js 是什么
是一个平台
- 它将多种技术组合起来
- 让JavaScript也能调用系统接口、开发后端应用
Node.js用到了那些技术
- V8 引擎
- libuv
- C/C++ 实现的 c-ares、http-parser、OpenSSL、zlib 等库
Node.js 技术架构
bindings 是什么
背景
- C/C++ 实现了一个http_parser库,很高效
- 如果你只会写JS,但是你想调用这个库,直接调用是不能成功的,需要一个中间的桥梁
bindings
- Node.js用C++对http_parser进行封装,使他符合某些要求,封装的文件叫做http_parser_bindings.cpp
- 用node.js提供的编译工具将其编译为.node 文件
- JS代码可以直接require 这个.node文件
- 这样JS就能调用C++库,中间的桥梁就是binding,由于Node.js提供了很多binding,就是bindings了。
编译成.node 文件不是必须的,可以是其他的任何可行方式
Node.js 工作流程
libuv 是什么
介绍
- FreeBSD 系统上有 kqueue
- Linux 系统上有 epoll,Windows系统上有IOCP
- Ryan(Node.js作者) 为了一个跨平台的异步I/O库,写了libuv,libuv会根据系统自动选择适合的方案
功能
- 可以用于TCP/UDP/DNS/文件等的异步操作
V8是什么
功能
- 将JS源代码变成本地代码并执行
- 维护调用栈,确保JS函数的执行顺序
- 内存管理,为所有对象分配内存
- 垃圾回收,重复利用无用的内存
- 实现JS的标准库
注意
- V8不提供 DOM API
- V8 执行 JS 是单线程的
- 可以开启两个线程分别执行JS
- V8 本身是包含多个线程的,如垃圾回收为单独线程
- 自带event loop 但 Node.js 基于libuv自己做了一个
Event Loop 是什么
什么是 Event
- 计时器到期了
- 文件可以读取了、读取出错了
- socket有内容了、关闭了
什么是 Loop
- loop 就是循环,比如while(true) 循环
- 由于事件是分优先级的,所以处理起来也是分先后的
- 所以Node.js需要按顺序轮询每种事件
- 这种轮询往往都是循环的,1->2->3->1->2->3
Event Loop
- 操作系统可以触发事件,JS可以处理事件
- Event Loop 就是对事件处理顺序的管理
举例
三种不同的事件
setTimeout(f1,100)
fs.readFile('/1.txt',f2)
server.on('close',f3)
如果同时触发,NodeJs会怎么办
- 肯定有某种顺序(优先级)
- 这种顺序应该是人为规定的
Event Loop
顺序示意图
重点阶段
- timers 检查计时器
- poll 轮询,检查系统事件
- check 检查 setImmediate 回调
- 其他阶段用的较少
注意
- 大部分事件,Node.js 都停在poll 轮询阶段
- 大部分事件都在poll 阶段被处理,如文件、网络请求
setTimeout(f1,0)
setImmediate(f2)
// 谁先执行? 不确定。
// 大部分情况下先执行setImmediate,因为JS停留在poll阶段的时间最长这个时候执行的时候先过check 检查 setImmediate 回调 看到有f2就执行了,然后执行到timers setTimeout有个f1 执行f1
// 部分情况是NodeJS刚进来的时候是先看timers这种情况会先执行f1
总结
- 用libuv 进行异步I/O操作
- 用 event loop 管理事件处理顺序
- 用C/C++库高效处理DNS/HTTP...
- 用bindings 让JS能和C/C++沟通
- 用V8运行JS
- 用Node.js标准库简化JS代码
- 这就是Node.js
Node.js API
官方地址
- 英文文档:nodejs.org/api
- 中文文档:nodejs.cn/api
民间版本
- devdocs.io,官方文档更像字典,民间版本搜索方便