一、Node.js不是什么
首先,不是另一个JavaScript框架,不是另一个jQuery、ExtJs、RequireJS、AngularJS。
其次,不是运行在浏览器中的,也不是运行在Web服务器里的,而是单独就能运行的。
Node.js和JavaScript有什么关系呢?Node.js采用的是JavaScript的语法,仅此而已。
需要注意的是Node.js采用的JavaScript是标准的ECMAJavaScript标准,由于不运行在浏览器中,所以不存在浏览器兼容性的问题。也没有DOM处理的相关事情。
二、Node.js是什么
1、Node.js是一个平台,是另一种语言
Node.js是一个平台。
为了帮助理解,我们可以把Node.js看作另外一种语言,只是这种语言碰巧采用了JavaScript的语法而已。
好吧,我们就把Node.js看作一种新的语言,这是一种脚本语言,脚本是解释执行的,所以需要一个解释器。
2008年发起的JavaScript引擎速度大战,极大提高JavaScript解释效率,V8是胜出者之一,Node.js直接采用V8作为JavaScript解释运行的底层支持(类似JVM之于Java)。
2、Node.js能做什么?
作为一个平台,一种语言,最基本的,可以开发基于命令行的或图形界面的桌面程序。
作为一种语言,Node.js支持基本的I/O操作,包括:文件I/O、网络I/O。
基于网络I/O能力,可以进一步实现连接数据库;
基于网络I/O能力,可以用来开发一个提供网络服务的服务器或客户端,如FTP、邮件服务器的服务器和客户端,如写个游戏外挂等。
一般来说,Node.js可完整地运行在Linux/Mac操作系统上,在Windows系统上,会越来越好,但不能保证所有的功能是完整健全的。
采用JavaScript的便捷语法,能做这么多事情,想象也有点小激动呢。
在这里,JavaScript终于升格为一等公民,同Java平起平坐了,不再是那个在浏览器里把Dom当主子伺候当受气小媳妇。
3、Node.js架构
为了实现这些功能,Node.js提供了Node标准库,采用JavaScript语法调用,方便到不行不行的。
为了支撑这些高层接口,底层是用C/C++编写的“Node下层接口”,如下图所示。
从Node.js架构图中可以看到,Node.js可清晰地分为三层:Node标准库、Node下层接口 和 更底层的支持。
更底层的支持中,V8我们前面提到过了,是解析JavaScript语法的引擎,那Libuv是什么呢?
这部分(Libuv、Libeio、Libev、IOCP)隐藏了Node.js最核心的一个秘密。
三、了不起的Node.js
当下流行的技术都是小巧而强大的,比如:nginx、redis、zookeeper等等,族繁不及备载。Node.js也是这样。
Node.js不仅仅在独立性和能力上超脱于浏览器中的同胞,这其中的差别好比当上总统的黑人相对于南方棉花园里的黑奴,甚至比这差别还大。
Node.js是为超大规模数据实时应用设计开发的,在性能上,它也把它的可怜同胞秒成渣。
看下面的对比数据:
四、Node.js的小秘密
为什么能取得这么好的成绩呢?现在给大家揭开这个秘密。
现在我们考虑一个问题,如何更充分地利用CPU资源。
有两个指标可以衡量,一个是CPU的空闲时间,一个是CPU线程的切换次数。
第一个指标:CPU空闲时间,空闲时间越少,效率越高。
第二个指标:我们都知道,CPU计算时间是分成时间片给线程使用的,操作系统负责调度,每次线程切换,需要保存当前现场到CPU外,把场子腾出来给别人用,恢复到时候反之,这是需要开销的,所以,切换次数越少,效率越高。
考虑到这些情况,Node.js采取“单线程+事件响应”作为基础的计算模型,这就是Node.js的核心秘密。
原理如下图所示,对比了完成同样的计算任务,多线程同步I/O和单线程异步I/O的区别。图中的“计算1”、“计算2”表示CPU在执行计算任务,“I/O”表示发生了I/O阻塞,CPU在空闲等待。
在单线程异步I/O(也就是Node.js采取的方式)中,CPU一直满负荷运转,没有等待的空闲时间。
同时,因为只有一个线程,无需进行进程切换。
回头看Node.js的架构图,Libuv的部分负责的就是事件驱动和异步I/O。
Libuv是Node.js为了统一不同实现做的一层接口抽象,Libeio、Libev、IOCP是具体实现。
至此,我们已经认识这位新朋友了。
是不是消除了好多误会呢?
Node.js这个名字着实起得不好。Node容易让人误会是Dom节点的意思。.js像极了 jQuery.js 中的.js。
真相大白了,Node.js着实和DOM和jQuery参商相隔,没有半毛钱关系,
五、Node.js的微内核
“异步事件模型”是Node.js的微内核,是Node.js的核心思想,是Node.js的主要方法论。
异步机制是Node.js的骨头,事件响应是Node.js的血。
1、基础编程模型
下面,看一段代码吧。
console.log('before db query');
db.query("select * from user",function(res){
//res.output();
console.log('finish db query');
})
console.log('after db query');
这段代码输出为:
before db query'
after db query
finish db query
解读一下,db.query的第二个函数是一个回调函数,也可以看作是事件响应函数。
执行完db.query,立即执行后面的console.log('after db query'),而不是等待数据库查询结果。
写过Java/PHP/C#数据库查询代码的童鞋马上脑补一下Java/PHP/C#代码是如何写的,如何执行的。等查询结果返回后才执行后面的语句,有木有?
这是Node.js的基本编程模型,读取文件的Api如下,伙伴们自行体会。
fs.read(filename,encoding,function(err,data){});
2、执行顺序
Node.js启动后,迅速把入口js文件中的语句逐条执行完,然后不断循环:
看一下是否有事件(如数据库查询完成)已经触发了,如果有,调用事件对应的回调函数,执行回调函数中的代码。
如果回调函数没有注册新的事件(如:发起数据库查询、发起 文件读写),则愉快地结束,继续下一次事件循环,等下一次事件触发。
如果回调函数中注册了新的事件,则放入到事件队列中。如下图所示。
六、Node标准库
Node标准库里都有啥呢?
可以到http://nodeapi.ucdok.com/api/查看Api文档。
console、util、fs、http等都是js最基本等模块。
本文只科普,代码层面的介绍另行叙述。
七、外围应用
Node.js的设计初衷是做一个碉堡天的Web应用,底层的API过于简单。
在Node标准库之上,又有应用层面的框架或工具供广大童鞋参考使用。
Express就是其中的一个,用于实现一个
另外还有大量基于Node.js的第三方工具,用于js合并发版的、用于单元测试的等。