Node.js入门指南
上QQ阅读APP看书,第一时间看更新

1.2 Node.js的发展历史和特点

你可能根本不会相信Node.js才十二岁,相比之下JavaScript已经有二十年的历史,这二十年中,JavaScript由一门非常简陋的浏览器端,仅能验证表单的语言,演化到前端的三大框架,即Vue.js、Angular.js、React.js,以及由最先开始的Node.js 0.1版本,演化到Node.js 16.7.0版本,研发速度之快令人咋舌。

1.2.1 JavaScript的发展历史

JavaScript最初由Netscape的Brendan Eich设计,最初将其脚本语言命名为LiveScript,后来Netscape在与Sun合作之后将其改名为JavaScript。图1-1是网景通信公司发布的Netscape浏览器。

图1-1 Netscape浏览器

1996年Netscape决定把JavaScript语言提交给ECMA国际进行标准化,于是,1997年该语言被正式标准化发布。1998年的ECMAScript2(简称ES2)和1999年的ECMAScript3(简称ES3)也先后发布。

在1999年发布ES3之后,官方标准出现了十年的沉寂,在此期间没有任何的变化,ES的第4版本的标准版起初还有一些进展,最终由于语言过于复杂被搁置。

由谷歌、微软、雅虎等讨论,决定在ES3上增加一些小范围的更新,这个标准命名为ES3.1,但是整个团队对于ES4具体包含的内容仍然讨论不休。2009年ES5发布了,由于很多浏览器厂商并没有遵循相关的标准,所以许多开发者并不知道这个现代化的ES5版本。

直到2015年整个事情终于出现了转机。TC39(ECMA国际的负责ECMAScript标准化委员会)持续推进标准化工作,将该版本最先被命名为ES6,即ECMAScript 2015,它包括许多新的特性,如类、模块、箭头函数、加强的对象字面量、模块化、字符串等结构,以及默认参数等方面的功能。但浏览器对这些新特性的支持是有限的,所以开发者只能进行转化,如把ES6转化为ES5,并且该委员会决定每年都会更新JavaScript的版本。

直到现在(截止本书写作时)ES20出现了,有更多的新功能被加入,使JavaScript的历史变得更加丰富。

1.2.2 Node.js的发展历史

Node. js发展分为三个阶段,第一个阶段是早期微软的ASP动态语言为后期的服务器端发展指明了方向,第二阶段是JS在服务器端的标准化,CommonJS为JS在服务器端的发展铺好了道路,第三阶段是Node.js的出现是服务器端发展的巅峰。

1.微软ASP动态语言的出现

早期开发一个网页需要使用大量的C语言,通过CGI的方法,实现动态的Web网页。但编程效率非常低,并且需要开发者具有丰富的开发经验。

1998年,微软ASP动态语言的出现,直接引发了一场革命,降低了动态网页开发的难度,并且还创新使用了大量的ADD组件,使访问数据库的方式变得更加方便快捷。

微软ASP动态语言的出现开创了一个时代,同时为后期的服务器端语言的发展奠定了基础。

2.JS的标准化-CommonJS的诞生

正如为了统一JavaScript语言的问题诞生了ECMAScript。CommonJS的诞生也是为了解决JavaScript语言没有统一标准的问题。CommonJS尝试通过创建一个统一的模块,使得大家接受一个可以使用JavaScript模块的脚本单元。就像C++函数可以非常方便地使用函数库形式一样。CommonJS仅是一套规范,而其是由众多语言实现的。Node.js就是其中的一个实现。

CommonJS包括模块、包、系统、二进制、控制台、编码、文件系统、套接字、单元测试等部分,这些部分相互依存。共同形成了如今的CommonJS规范。

3.Node.js巅峰的诞生

Node. js是JavaScript语言在服务器端发展的巅峰。

2009年,第一版Node.js从Github开源仓库里正式开源,并创建了NPM包管理器及相关的生态系统。

2010年,第一版的Express.js Web框架诞生,标志Node.js的第一版框架诞生。

2011年,随着生态成熟,Node.js的使用率因众多大型企业的采用而逐步飙升,并保持高速的增长。

2013年,第一大Node.js博客平台发布了Ghost, Node.js开始逐渐步入普通的使用者中。

2015年,Node.js基金会诞生,Node.js开始正式引入商业化运作。

Node. js将在未来继续保持良性发展,成为一个更大的平台。

1.2.3 Node.js的特点与未来版本

Node. js最大特点是采用了异步I/O和事件驱动架构设计,这种架构设计巧妙避开了原先Apache Server的多线程的思路,直接使用了单线程,从而具有高并发的特点。传统的多线程模型是每个业务逻辑提供一个系统的线程,通过系统线程的切换弥补I/O在时间调用上的消耗。Node.js采用单线程模型,对于所有的I/O都采用异步请求,从而避免因上下文频繁切换而导致的耗时操作。Node.js在执行过程中还会使用一个异步队列,通过不断的循环队列从而等待程序进程的处理。

对于一个SQL查询来说,其代码如下:

上方的代码为PHP代码,首先使用query对SQL语句进行查询,然后把查询的结果使用echo输到HTML页面中。在上方的代码中,调用query进行查询的时候,由于SQL查询涉及硬盘、网络等时延较长的操作,会产生阻塞,从而影响后续代码的执行。而Node.js的查询代码如下:

其中,

为Node.js的回调函数,只有当SQL执行完毕后,才会执行相应的回调函数。这样就避免了相应的SQL查询阻塞当前程序运行的问题。

Node. js的异步操作是基于事件实现的,所有涉及耗时的操作,如磁盘I/O、网络通信、数据库查询都是基于事件,而非阻塞实现的,其实现过程如图1-2所示。

图1-2 Node.js事件与回调的过程

其核心拥有一个事件循环,所以判断是否有事件,如果有事件,则取出相应的事件,然后进行执行,执行完毕以后再次判断是否有关联的回调,如果有回调则执行相应的回调,如果没有回调则至此该事件执行完毕。

这种Node.js的事件循环方式,可以增加Node.js应用程序运行的健壮性以及可用性。

但同时,这种异步基于事件的编程方式其弊端也是显而易见的,因为其不符合开发者正常的线性开发思路,会造成开发艰难,容易出错。不利于开发者开发应用。

由于Node.js采用了异步I/O和事件驱动,虽然不利于开发,但其在性能上的提升是显而易见的。

经过Snoopyxd详细的对比Node.js与PHP+Nginx的组合,结果显示在3000并发连接、30s的测试下,输出“Hello World”请求的结果如下:

◎PHP每秒响应请求数为3624,平均每个请求响应时间为0.39s;

◎Node.js每秒响应请求数为7677,平均每个请求响应时间为0.13s。

同样的测试,对MySQL查询操作的结果如下:

◎PHP每秒响应请求数为1293,平均每个请求响应时间为0.82s;

◎Node.js每秒响应请求数为2999,平均每个请求响应时间为0.33s。

经过对比可以发现,Node.js无论是在处理请求上,还是在MySQL查询操作上,其性能都优于PHP+Nginx的组合。

Node. js的开发者Ryan DahI于近日在Github上创建了一个新项目——Deno。该项目使用Rust语言来封装V8引擎,并使用Tokio库来构建事件的循环系统,具有以下的功能特点:

◎默认为安全,外部的代码没有文件系统、网络、环境的访问权限;

◎支持开箱即用的TypeScript环境;

◎只分发一个独立的可执行文件;

◎具有内建的工具箱,如代码格式化工具;

◎具有一组能通过审计的标准模块;

◎脚本文件能够打包成一个单独的JavaScript文件。

Deno的出现很可能是Node.js的未来,也许某天,Deno会取代Node.js成为JavaScript语言在服务器端的核心。