为什么使用 Node
假设你正在开发一个广告服务器, 每分钟需要发布几百万条的广告. Node
的非阻塞 I/O 将是一个高效的解决方案, 因为服务器能够最大限度地利用到所有的 I/O
资源, 而这一切不需要你写特殊的底层代码. 并且, 假如你已经有一支会写 JavaScript 的开发团队, 那么他们应该可以直接参与到 Node
的项目中. 传统的 web 平台将无法做到这一点, 这也是为什么像微软这样的公司也在积极地推动 Node, 尽管他们已经有了像. NET
那么优秀的平台. Visual Studio(.NET IDE) 的用户可以安装一些工具来支持对 Node
的智能提示, 性能监测, 甚至 npm. 微软还开发了 WebMatrix, 它不但能直接支持 Node, 而且还能部署 Node 项目.
Node
把非阻塞 I/O 作为提高某些类型应用的性能的方式. JavaScript
传统的事件机制意味着在异步编程中, 它有着相对方便以及容易理解的语法. 在传统的编程语言中, I/O 的操作将阻塞进程直到它完成为止. Node
的异步文件读写以及网络 API 意味着在这些相对较慢的 I/O 操作处理的时候主进程仍然能处理其他请求. 下图展示了如何使用异步的网络和文件 API
同时处理多个任务.
web 前端学习扣 qun:437813258 免费领取全套教学视频资料!
在图中, Node
的 http 模块接收到并且解析了一个新的 HTTP 请求
, 然后服务端的应用代码使用异步接口, 将一个回调函数传入数据库的读取函数中来进行一次数据查询. 在等待数据返回的同时服务器能够从文件系统中读取网页模板文件
, 这个模板文件被用来展示网页. 一旦数据库完成查询, 模板内容和数据库的返回数据将被用来渲染页面.
在服务器处理这个请求的同时, 服务器还可以用可用的资源处理其他的请求 . 在不用考虑多线程的情况下开发这个广告服务, 你可以仅使用最基本的 JavaScript 编程技术, 通过 Node, 非常高效地使用服务器 I/O 资源.
其他 Node
适用的场景是 Web API 和网络爬虫, 如果你需要下载以及截取网页的内容, 那么 Node 将是非常完美的解决方案, 因为它能模拟 DOM
操作, 并且运行客户端 JavaScript 脚本. 而且在这个场景中, Node 有着性能优势, 因为网络爬虫主要的消耗在于网络和文件读写的 I/O.
假如你需要调用或者开发一个 JSON API,Node 也是一个非常棒的选择, 因为它使得操作 JavaScript 对象变得非常简单. Node 的一些 web 框架 (例如 express) 能够快速地搭建 JSON API.
Node 不仅仅局限于 web 应用, 你可以创建任意你想要的 TCP/IP 服务, 比如网络游戏服务器, 通过 TCP/IP 套接字向各类玩家发送游戏状态, 也可以在后台任务中维护游戏数据, 将数据发送给玩家.
什么时候使用 Node
下面是一些 Node 适用的应用例子, 来帮你像一个真正的 Node 开发者一样来考虑这个问题.
情景: 广告分布系统
Node 的强项:
有效地分配小块信息
处理潜在的网络速度慢的连接
容易扩展为多个处理器或服务器
情景: 游戏服务器
Node 的强项:
使用 JavaScript 来构建业务逻辑模型
不使用 C 语言来开发迎合特定网络的服务器程序
情景: 内容管理系统, 博客
Node 的强项:
对已经有客户端 JavaScript 开发经验的团队来说, 可以很轻松地创建 RESTful JSON APIs
轻量的服务器, 和浏览器端 JavaScript 结合
Node 的主要特性
Node 的主要特性是它的标准类库, 模块系统以及 npm(包管理系统), 当然还有很多其他的.
实际上 Node 最强大的特性是它的标准类库, 它主要由二进制类库以及核心模块两部分组成, 二进制类库包括 libuv , 它为网络以及文件系统提供了快速的事件轮循以及非阻塞的 I/O. 同时它还有 http 类库, 所以你可以很快确定你的 http 客户端与服务端.
web 前端学习扣 qun:437813258 免费领取全套教学视频资料!
上图是对 Node 内部的高层次概述, 展示了各个模块是如何组合的.
Node
的核心模块主要由 JavaScript 编写, 也就是说, 假如你不理解或者你想了解更多细节, 你可以直接阅读 Node
的源码. 这不但包括像网络, 文件操作, 模块系统, 以及 stream 这些模块, 还包括 Node 特有的特性, 例如, 通过 cluster
模块同时运行多个 Node 进程, 以及可以将代码片段封装在事件驱动的异常处理中的 domain 模块.
接下来, 我们将从事件开始深入每个核心模块.
1. EventEmitter 事件的接口
每个 Node 开发者迟早会碰到 EventEmitter , 一开始, 它像是那些只有类库开发者才会使用的东西, 但实际上它是大多数 Node 核心模块的基础, Stream, 网络, 文件系统全部继承于它.
你可以基于 EventEmitter
来创建自己基于事件的 API, 例如你要开发一个 paypal 付款处理的模块, 你可以让它基于事件, 这样 Payment 对象的实例可以触发像 paid
和 refund 这样的事件, 通过这样的设计, 你可以将这个模块从你的业务逻辑中分离出来, 让它可以在其他项目中被重用.
一个有意思的地方是, stream 模块也是基于 EventEmitter 的.
2. Stream: 高可扩展性 I/O 的基础
Streams
继承于 EventEmitters , 能被用来在不可预测的输入下创建数据, 比如网络连接, 数据传输速度取决于其他用户正在干什么. 通过 Node
的 stream API, 你可以创建一个对象接收关于连接的事件, 在接收到新数据时触发 data 事件, 在结束连接时触发 end
事件, 在有错误发生时触发 error 事件.
相比较把许多的回调函数传入一个 readable stream
的构造函数, 你只订阅你关心的事件要好得多, 多个 streams 也可以连接起来, 这样你可以用一个 stream
对象从网络读取数据, 把读取到的数据输送到另外一个 stream 中加工成另外一个对象, 可以把 xml 文件的数据读取出来转换成 JSON
格式, 让 JavaScript 操作起来更容易.
你可能觉得 stream 和事件听上去很抽象, 没错, 它们的确很抽象, 但它们是 I/O 模块 (例如文件系统和网络) 的基础.
3. FS: 处理文件
Node 的文件模块不但可以通过非阻塞的 I/O 读写文件, 而且它也有同步的方法. 你可以通过 fs.stat 异步获取文件的信息, 也可以通过 fs.statSync 同步读取.
如果你想通过 Stream 的方式高效地处理文件内容, 那么你可以通过 fs.createReadStream 来获得一个 ReadableSream 对象.
4. 网络: 创建网络客户端与服务端
网络模块是 http 模块的基础, 也可以用来创建通用的网络客户端与服务端. 尽管 Node 开发通常指的是 web 开发, 在第 7 章你会看到如何创建 TCP 和 UDP 的服务, 这意味着你并不局限于 http 开发.
5. 全局对象与其他模块
假如你有用 Node 开发 web 应用的经验, 也许是 Express 框架, 那么你也许并不知道你已经使用了 http ,net 以及 fs 等核心模块. 其他的内置模块也许不那么吸引眼球, 但也是至关重要的.
全局对象与方法的设计就是其中一例, 比如 process
对象, 它让你可以把数据传入或者传出标准 I/O 流(stdout,stdin). 就像在 UNIX 或者 Windows
脚本中, 你可以把数据通过 cat 直接传给 Node 程序. 还有无处不见的 console 对象, 所有的 JavaScript
开发都爱它, 也是一个全局对象.
了解 Node 特性后, 我们来看看Node.js 硬实战: 115 个核心技巧一书的精简版目录.
第一部分 Node 基础
1 入门
2 全局变量: Node 环境
3 Buffers: 使用比特, 字节以及编码
4 Events: 玩转 EventEmitter
5 流: 最强大和最容易误解的功能
6 文件系统: 通过异步和同步的方法处理文件
7 网络: Node 真正的 "Hello, World"
8 子进程: 利用 Node 整合外部应用程序
第二部分实践中的技巧
9 网络: 构建精简的网络应用
10 测试: 编写健壮代码的关键
11 调试: 用于发现和解决问题
12 生产环境中的 Node: 安全地部署应用程序
第三部分编写模块
13 编写模块, 掌握 Node 的所有
来源: http://www.jianshu.com/p/f5a72a89a6bb