Node技术架构
# 0.前言
在转载文章《setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop》 (opens new window)已经对EventLoop讲解的很通透了。
只是,文章在其中一小节 #JS异步是怎么实现的 仅举例说明了在浏览器中是如何处理异步事件,而没有对Node.js做出详细的说明。
同时,根据蒋鹏飞的文章我们又了解到浏览器和 Node 中的 EventLoop是不同的,这又是怎么回事吗?难道在Node 除了v8引擎外,还封装了一个异步事件处理机制吗?
答案:是的。
实际上Chrome浏览器的异步实现机制是借助V8引擎的能力,而要介绍 v8引擎,又绕不开对 Node.js 技术架构的分析。
# 1.Node技术架构
# 技术架构图

# 第一层:Node API
在Node.js有许多官方实现的函数库,如http模块、fs文件读取模块、stream流模块等。
通过Node.js提供的标准库,我们很清晰的能够感觉到Node主要特性就是提供对数据流异步执行的方式。
# 第二层:bindings|C++
我们先来看下的场景:
- 现在市面上已经有一个
C/C++实现的库http_parser,很高效。 - 我们只会
JS,不会也不想学JS,但是又想拥有这个库的能力。
那有没有办法能?有,就是通过这里的bindings实现的。
Node.js bindings是什么?它是连接JS和C/C++通信的一座桥梁。
即,我们既可以通过JS去调用C++代码,也可以在C++中使用JS代码。
参考资料:
# 第三层:见github Node.js 的deps目录
这一层主要介绍
Node的一些依赖库,这里重点关注两个库:libuv和v8。
Node.js v0.10/deps

# 2. libuv和v8简介
# libuv库
在不同系统上,对异步的实现是各不相同的,如:
FreeBSD系统:kqueueLinue系统:epollWindows系统:ICOP
而libuv则是一个跨平台的异步I/O库,它会根据系统自动选择合适的方案。
# V8库
也就是Chrome浏览器内置的JS解析器,它除了可以执行JS外,可附带以下功能:
- 将JS源代码变为本地代码
- 维护调用栈,确保JS函数的执行顺序。
- 内存管理
- 给所有对象分配内存
- 垃圾回收:将不用的内存资源回收,再分配。
- 实现
JS的标准库(第一层Node提供的API)
# 3.EventLoop
基于对Node.js技术架构分析。
JS的异步执行首先需要分清楚执行环境是:浏览器(V8) 还是 Node。
在浏览器环境中,实际上调用的是
v8中对异步的调用,可分为:宏任务:macroTask微任务:microTaskPS:终于知道微软为啥叫
microsoft了,记住micro前缀。
而在Node环境中,虽然也集成了
v8,但是异步处理使用的libuv的异步I/O跨平台实现,对不同的异步事件分的执行优先级区分更细,有六个阶段,这里与前端有关的主要有三个:timers(执行定时器回调)poll(停留)check(setImmediate)
# 4.面试中常考的一道问题
考题:setTimeout与setImmediate到底谁快谁慢。
答:不确定,在同步函数执行阶段,我感觉setTimeout会快些(误:纯个人理解记忆) 。在回调函数等执行函数中,setImmediate快。
这一部分请详细看:转载文章《setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop》
# 5. 🚨注意
Node不是一门后端编程语言,不是一个web框架
正确的表述:
Node.js是一个平台,让JavaScript能调用系统接口、开发后端应用。Node中的线程知识补充:
我们知道浏览器中渲染进行可以分为以下线程
那
V8中与浏览器的线程的不同在于:V8缺少DOM API,DOM是浏览器提供的。
相同的在于:
V8执行JS是单线程,本身多线程,如垃圾回收线程。
# 总结
本篇博文主要是转载文章的补充,核心观点是:
- 浏览器的异步处理:取决于
v8 - Node的异步处理:取决于
libuv
# 补充资料:浏览器内核
在本文中,默认v8是浏览器的内核其实是不严谨的,这边附上常见浏览器JS引擎和内核的列表(不完全):
| 公司 | 浏览器 | JS引擎 | 渲染引擎 |
|---|---|---|---|
| Microsoft | IE6-8 | JScritp | Trident |
| IE9-11 | Chakra | Trident | |
| Edge | Chakra | Edge | |
| Mozilla | Firefox | JagerMonkey | Gecko |
| Chrome | V8 | Blink | |
| Apple | Safari | Webkit | SquirrelFish Extreme |
| Opera | Opera12.16+ | Blink | Carakan |