1.1 Node.js是什么
你很有可能已经听说过Node.js,甚至已经用上了。的确,近年来不管是Web/服务端还是桌面/移动应用的开发都可以看到它的身影。它在GitHub上拥有64000多颗星(Star),拥有2500多位贡献者,官方的包管理平台NPM下拥有高达100多万的软件包(Package)。所有这些都表明Node.js的强大活力。
官网上(https://nodejs.org)给Node.js的定义是:
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,用于构建高速、可伸缩的网络应用程序。Node.js采用的事件驱动、非阻塞I/O模型,使它既轻量又高效,是构建可扩展的网络应用程序的完美选择。
1.JavaScript引擎
JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。目前为止一些知名的JavaScript引擎如下:
· V8引擎:Chrome浏览器采用的JavaScript引擎,也是第一个使用JIT技术的引擎。
· JavaScriptCore:Safari浏览器采用的JavaScript引擎。
· Chakra:IE/Edge浏览器采用的JavaScript引擎。
· SpiderMonkey:Mozilla Firefox浏览器采用的JavaScript引擎。
为什么会有这么多的JavaScript引擎呢?
主要是因为历史的原因,1995年,网景(NetScape)公司开发了一种运行在浏览器的脚本语言,最初命名为Mocha,后来改名为LiveScript,临近发布的时候为了蹭一蹭Java的热度,最终命名为JavaScript。直到1997年,JavaScript才被欧洲计算机制造商协会(ECMA)进行了标准化,标准编号为ECMA-262,标准化后的名称为ECMAScript。
ECMAScript只是一种语言规范,满足该规范的语言都可以称为“ECMAScript兼容”。现在比较出名的是JavaScript语言,早些年还有ActionScript(Flash使用的脚本语言)。
2.V8引擎
V8是一个由Google公司开发的开源JavaScript引擎,使用C++编写,用于Google Chrome浏览器和Google Chromium浏览器。
V8在运行之前将JavaScript编译成了机器代码,而非字节码或是解释执行它,以此提升性能。此外,V8还使用了如内联缓存(Inline Caching)等技术来提高性能。有了这些功能,JavaScript程序在V8引擎上的速度可以媲美二进制编译程序的执行速度。
Node.js也因为采用了V8引擎才有如此高的JavaScript执行效率。
3.事件驱动
事件驱动程序设计(Event-Driven Programming)是一种计算机程序设计模型。这种模型的程序运行流程是由用户的操作(如鼠标的按键、键盘的按键操作)或者是由其他程序的消息来驱动的。
事件驱动的程序至少会有一个事件队列,当有新的请求进来时会被插入到队列中,然后通过循环来检测队列中的事件,当发现有一个事件发生时就会调用回调函数。
Node.js的JavaScript(JS)线程是单线程运行的,通过一个事件循环(Event Loop)来循环取出消息队列(Event Queue)中的消息进行处理,处理过程基本上就是去调用该消息对应的回调函数。
4.非阻塞I/O
I/O模型的一种,与之相对的还有阻塞I/O。
简单来说,阻塞I/O就是进行I/O操作的时候,进程会被阻塞,直到I/O操作完成后进程才会解除阻塞状态继续执行。而非阻塞I/O在进行I/O操作时,进程不会被阻塞,进程继续执行;如果需要知道I/O操作的结果,可以通过轮询的方式。
5.Node.js的模块架构
Node.js核心基于libuv框架,由C/C++编写。图1-1所示是Node.js的模块架构图。
图1-1
6.Node standard library(Node标准库)
Node.js标准库由JavaScript编写而成,它提供网络、文件、事件等操作,可以认为是一层比较薄的API封装层,实际的操作还是由底层来完成。
7.Node bindings(Node绑定层)
Node.js底层使用了大量的C/C++代码,是高性能的保证。不过,JavaScript代码是怎么和这些C/C++代码相互调用的呢?这里不是使用了好几种语言吗?
一般来说,不同语言之间的规范不同,所以写出来的代码无法直接沟通,这时候就需要Bindings层,它是一些胶水代码,能够把不同的语言绑定在一起使其能够相互沟通。在Node.js中,Bindings层所做的就是把底层的C/C++接口暴露给JavaScript环境,从而打通JavaScript与C/C++之间的相互调用。
8.libuv
libuv是提供异步功能的C库。它在运行时负责一个事件循环(Event Loop)、一个线程池、文件系统I/O、DNS相关的I/O和网络I/O,以及一些其他重要功能。
9.其他的C/C++组件和库
如C-ares、http_parser、OpenSSL以及zlib等,这些依赖提供了对系统底层功能的访问,比如网络、压缩、加解密,等等。