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
系统:kqueue
Linue
系统:epoll
Windows
系统:ICOP
而libuv
则是一个跨平台
的异步I/O
库,它会根据系统自动选择合适的方案。
# V8库
也就是Chrome
浏览器内置的JS解析器
,它除了可以执行JS外,可附带以下功能:
- 将JS源代码变为本地代码
- 维护调用栈,确保JS函数的执行顺序。
- 内存管理
- 给所有对象分配内存
- 垃圾回收:将不用的内存资源回收,再分配。
- 实现
JS
的标准库(第一层Node提供的API
)
# 3.EventLoop
基于对Node.js
技术架构分析。
JS
的异步执行首先需要分清楚执行环境是:浏览器(V8)
还是 Node
。
在浏览器环境中,实际上调用的是
v8
中对异步的调用,可分为:宏任务
:macroTask
微任务
:microTask
PS:终于知道微软为啥叫
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 |