Node的诞生
Node.js 是一个开源与跨平台的 JavaScript 运行时环境。简单的来说,他是运行在服务端而非浏览器端的JS代码。Node.js不是凭空出现的项目,也不是某个Web前端工程师为了完成将JavaScript应用到服务端的理想而在实验室里捣鼓出来的。它的出现主要归功于Ryan Dahl历时多年的研究,以及一个恰到好处的节点。2008年V8随着Chrome浏览器的出世,JavaScript脚本语言的执行效率得到质的提升,这给Ryan Dahl带来新的启示,他原本的研究工作与V8之间碰撞出火花,于是带来了一个基于事件的高性能Web服务器。 由此开始,前端界的新秀诞生了。

Node的命名与起源
Ryan Dahl是一名资深C/C++程序员,在创造出Node之前,他的主要工作都是围绕高性能Web服务器进行的。经历过一些尝试和失败之后,他找到了设计高性能Web服务器的几个要点:事件驱动、非阻塞 、I/O 。所以他最初目标是写一个基于事件驱动、非阻塞 I/O 的Web服务器,以达到更高性能,提供Apache等服务器之外的选择。在选取Node的实现语言的时候,Ryan Dahl评估过 C,Lua,Haskell、Ruby等语言作为备选,结论为:C的开发门槛高;自己不足以玩转 Haskell;Lua 自身包含太多阻塞 I/O 库,难以改变人们习惯;而Ruby则是虚拟机性能低。相比之下,JavaScript比 C的开发门槛要低,比Lua的历史包袱少。尽管服务器JavaScript已存在多年,但作为后端部分一直没有市场,可以说历史包袱为零,为其导入非阻塞 I/O 没有额外阻力。另外,JavaScript在浏览器中有广泛的事件驱动方面的应用,暗合了Ryan Dahl喜好基于事件驱动的需求。当时,Chrome浏览器的JavaScript引擎V8也摘得性能第一的桂冠,而其基于新BSD许可证发布,受到Ryan Dahl的欢迎。所以,JavaScript成了Node的实现语言。
起初,Ryan Dahl称他的项目为 web.js ,就是一个Web 服务器,但是项目的发展超过了他最初单纯开发一个Web服务器的想法,变成了构建网络应用的一个基础框架,这样可以在它的基础上构建更多东西,诸如服务器、客户端、命令行工具等。Node发展为一个强制不共享任何资源的单线程、单进程系统,包含十分适宜网络的库,为构建大型分布式应用程序提供基础设施,其目标也是成为一个构建快速、可伸缩的网络应用平台。它自身非常简单,通过通信协议来组织许多Node,很容易通过扩展达成构建大型网络应用的目的。每个Node进程都构成这个网络应用中的一个节点,这是它名字所含意义的真谛。
Node给JavaScript带来了什么?
简单来说,Node为Js解决了三个痛点问题:
- 更好的组织代码,提升复用性。当然在ES6中这一点也得到了很大的提升。
- 处理文件与数据库。
- 与互联网进行沟通,以标准化的格式处理请求并发送回答。
在这些的基础上,事件驱动,异步编程,非阻塞式io这些使前端开发者能够用JS做更多的事情。由此开始,前端开始操作后端的业务,大前端的说法也出现了。
Node 的特点
- 异步I/O: Node保留了前段浏览器JavaScript中那些熟悉的接口,没有改写语言本身的任何特性,依旧基于作用域和原型链,区别在于它将前段中广泛运用的思想迁移到了服务器端。 在Node中,绝大多数的操作都是以异步的方式进行调用。Ryan Dahl排除万难,在底层构建了很多异步 I/O 的API,从文件读取到网络请求等,均是如此。这样的意义在于,在Node中,我们可以从语言层面很自然的进行 并行 I/O 操作。每个调用之间无需等待之前的 I/O 调用结束。
- 回调函数: 与其它的Web后端编程语言相比,Node除了异步和事件外,回调函数是一大特色。纵观下来,回调函数也是也是最好的接受异步调用返回数据的方式。但这种编程方式对于很多习惯同步思路编程的人来说,也许是十分不习惯的。代码的编写顺序与执行顺序并无关系,这对他们可能造成阅读上的障碍。在流程控制方面,因为穿插了异步方法和回调函数,与常规的同步方式相比,变得不那么一目了然了。
- 单线程:
Node保持了JavaScript在浏览器中单线程的特点。而且在Node中,JavaScript与其余线程是无法共享任何状态的。单线程的最大好处是不用像多线程编程那样处处在意状态同步的问题,这里没有死锁的存在,也没有线程上下文交换所带来的性能上的开销。同样,单线程也有它的弱点,这些弱点是学习Node过程中必须要面对的。积极面对这点,可以享受到Node带来的好处,也能避免潜在问题,使其得以高效利用。单线程的弱点具体有一下3个方面:
- 无法利用多核CPU。
- 错误会引起整个应用退出,应用的健壮性值得考研。
- 大量计算占用CPU导致无法继续调用异步I/O。 像浏览器中JavaScript与UI共用一个线程一样,JavaScript长时间执行会导致UI的渲染和响应被中断。在Node中,长时间的CPU占用也会导致后续的异步I/O发不出调用,已完成的异步I/O的回调函数也会得不到及时执行。
总结
本章初步的介绍了什么的NodeJs,以及NodeJs的时间线和大事记。NodeJs作为一门已经出现了10年的产物,用到了很多前端业界通用的思想和设计,可以说,学习NodeJs不仅仅是知识的增加,更是对技术底层的一种理解,了解平时常用的浏览器端的JS是如何被设计到在服务端运行的,为什么保留了单线程等问题。由于笔者水平低下,可能文中存在错误,恳请留言指点。