【读书笔记】Node.js开发指南

一:Node.js是什么?

正如当年为了统一 JavaScript 语言标准,人们制定了 ECMAScript 规范一样,如今为了统一 JavaScript 在浏览器之外的实现, CommonJS 诞生了。 CommonJS 试图定义一套普通应用程序使用的API,从而填补 JavaScript 标准库过于简单的不足。 CommonJS 的终极目标是制定一个像 C++ 标准库一样的规范,使得基于 CommonJS API 的应用程序可以在不同的环下运行,就像用 C++ 编写的应用程序可以使用不同的编译器和运行时函数库一样。为了保持中立, CommonJS 不参与标准库实现,其实现交给像 Node.js 之类的项目来完成。Node.js 是目前 CommonJS 规范最热门的一个实现,它基于 CommonJS Modules/1.0 规范实现了 Node.js 的模块,同时随着 CommonJS 规范的更新, Node.js 也在不断跟进。

?

二:搭建开发环境

快速搭建 Node.js / io.js 开发环境以及加速 npm

?

三:使用

使用 node REPL 模式
REPL Read-eval-print loop),即输入求值输出循环。如果你用过 Python,就会知
道在终端下运行无参数的 python 命令或者使用 Python IDLE 打开的 shell,可以进入一个即时求值的运行环境。 Node.js 也有这样的功能,运行无参数的 node 将会启动一个 JavaScript的交互式 shell

Cmd node 连续两次ctrl+c+c退出

技术分享

mkdir 创建目录 touch 新建文件 node test.js运行

?

技巧——使用 supervisor
如果你有 PHP 开发经验,会习惯在修改 PHP 脚本后直接刷新浏览器以观察结果,而你在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止Node.js 再重新运行才会奏效。这是因为 Node.js 只有在第一次引用到某部份时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,而 PHP 则总是重新读取并解析脚本(如果没有专门的优化配置)。 Node.js的这种设计虽然有利于提高性能,却不利于开发调试,因为我们在开发过程中总是希望修改后立即看到效果,而不是每次都要终止进程并重启。supervisor 可以帮助你实现这个功能,它会监视你对代码的改动,并自动重启 Node.js
使用方法很简单,首先使用 npm 安装 supervisor
$ npm install -g supervisor
接下来,使用 supervisor 命令启动 app.js
$ supervisor app.js当代码被改动时,运行的脚本会被终止,然后重新启动。在终端中显示的结果如下:

四:单线程事件驱动的异步IO

什么是阻塞(block)呢?线程在执行中如果遇到磁盘读写或网络通信(统称为 I/O 操作),通常要耗费较长的时间,这时操作系统会剥夺这个线程的 CPU 控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为 阻塞。当 I/O 操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种 I/O 模式就是通常的同步式 I/O(Synchronous I/O)或阻塞式 I/O (Blocking I/O)。

相应地,异步式 I/O (Asynchronous I/O)或非阻塞式 I/O (Non-blocking I/O)则针对所有 I/O 操作不采用阻塞的策略。当线程遇到 I/O 操作时,不会以阻塞的方式等待 I/O 操作的完成或数据的返回,而只是将 I/O 请求发送给操作系统,继续执行下一条语句。当操作系统完成 I/O 操作时,以事件的形式通知执行 I/O 操作的线程,线程会在特定时候处理这个事件。为了处理异步 I/O,线程必须有事件循环,不断地检查有没有未处理的事件,依次予以处理。

阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的 CPU 核心利用率永远是 100%,I/O 以事件的方式通知。在阻塞模式下,多线程往往能提高系统吞吐量,因为一个线程阻塞时还有其他线程在工作,多线程可以让 CPU 资源不被阻塞中的线程浪费。而在非阻塞模式下,线程不会被 I/O 阻塞,永远在利用 CPU。多线程带来的好处仅仅是在多核 CPU 的情况下利用更多的核,而Node.js的单线程也能带来同样的好处。这就是为什么 Node.js 使用了单线程、非阻塞的事件编程模式。

单线程事件驱动的异步式 I/O 比传统的多线程阻塞式 I/O 究竟好在哪里呢?简而言之,异步式 I/O 就是少了多线程的开销。对操作系统来说,创建一个线程的代价是十分昂贵的,需要给它分配内存、列入调度,同时在线程切换的时候还要执行内存换页, CPU 的缓存被清空,切换回来的时候还要重新从内存中读取信息,破坏了数据的局部性。

当然,异步式编程的缺点在于不符合人们一般的程序设计思维,容易让控制流变得晦涩难懂,给编码和调试都带来不小的困难。习惯传统编程模式的开发者在刚刚接触到大规模的异步式应用时往往会无所适从,但慢慢习惯以后会好很多。尽管如此,异步式编程还是较为困难,不过可喜的是现在已经有了不少专门解决异步式编程问题的库(如async)

?

五:包和模块

Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。在开发者看来,事件由 EventEmitter 对象提供

模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个

Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码、 JSON 或者编译过的 C/C++ 扩展。在前面章节的例子中,我们曾经用到了 var http = require(‘http‘), 其中 http是 Node.js 的一个核心模块,其内部是用 C++ 实现的,外部用 JavaScript 封装。我们通过require 函数获取了这个模块,然后才能使用其中的对象。

包是在模块基础上更深一步的抽象, Node.js 的包类似于 C/C++ 的函数库或者 Java/.Net的类库。它将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制。 Node.js 根据 CommonJS 规范实现了包机制,开发了 npm来解决包的发布和获取需求。Node.js 的包是一个目录,其中包含一个 JSON 格式的包说明文件 package.json。严格符合 CommonJS 规范的包应该具备以下特征:

? package.json 必须在包的顶层目录下;

? 二进制文件应该在 bin 目录下;

? JavaScript 代码应该在 lib 目录下;

? 文档应该在 doc 目录下;

? 单元测试应该在 test 目录下。

Node.js 对包的要求并没有这么严格,只要顶层目录下有 package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,严格遵守 CommonJS 规范。

?

?

在使用 npm 安装包的时候,有两种模式:本地模式和全局模式。默认情况下我们使用 npm install命令就是采用本地模式,即把包安装到当前目录的 node_modules 子目录下。Node.js require 在加载模块时会尝试搜寻 node_modules 子目录,因此使用 npm 本地模式安装的包可以直接被引用。
npm 还有另一种不同的安装模式被成为全局模式,使用方法为:
npm [install/i] -g [package_name]
与本地模式的不同之处就在于多了一个参数 -g。我们在 介绍 supervisor那个小节中使用了 npm install -g supervisor 命令,就是以全局模式安装 supervisor
为什么要使用全局模式呢?多数时候并不是因为许多程序都有可能用到它,为了减少多重副本而使用全局模式,而是因为本地模式不会注册 PATH 环境变量。举例说明,我们安装supervisor 是为了在命令行中运行它,譬如直接运行 supervisor script.js,这时就需要在 PATH环境变量中注册 supervisor npm 本地模式仅仅是把包安装到 node_modules 子目录下,其中的 bin 目录没有包含在 PATH 环境变量中,不能直接在命令行中调用。而当我们使用全局模式安装时, npm 会将包安装到系统目录, 譬如 /usr/local/lib/node_modules/ 同时 package.json 文件中 bin 字段包含的文件会被链接到 /usr/local/bin/ /usr/local/bin/ 是在PATH 环境变量中默认定义的,因此就可以直接在命令行中运行 supervisor script.js命令了。

?

技术分享

?

六:调试

命令行调试

Node.js 支持命令行下的单步调试。下面是一个简单的程序:

?

远程调试
V8 提供的调试功能是基于 TCP 协议的,因此 Node.js 可以轻松地实现远程调试。在命令行下使用以下两个语句之一可以打开调试服务器:
node --debug[=port] script.js
node --debug-brk
[=port] script.js

?

使用 Eclipse 调试 Node.js
基于 Node.js 的远程调试功能,我们甚至可以用支持 V8 调试协议的 IDE 调试,例如强大的 Eclipse Eclipse 是深受广大"码农"喜爱的集成开发环境,有 Java 开发经验的对它一定不会陌生。

?

使用 node-inspector 调试 Node.js
大部分基于 Node.js 的应用都是运行在浏览器中的,例如强大的调试工具 node-inspectornode-inspector 是一个完全基于 Node.js 的开源在线调试工具,提供了强大的调试功能和友好的用户界面,它的使用方法十分简便。
首先,使用 npm install -g node-inspector 命令安装 node-inspector,然后在终
端中通过 node --debug-brk=5858 debug.js 命令连接你要除错的脚本的调试服务器,启动 node-inspector
$ node-inspector
在浏览器中打开 http://127.0.0.1:8080/debug?port=5858 即可显示出优雅的 Web 调试工具

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。