描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302487807丛书名: Web前端技术丛书
本书分为8章6个附录,讲解了Node.js的各种基础特性,使读者快速入门,同时结合语言*的发展趋势,让读者能够紧跟技术潮流。本书围绕Node.js在Web站点开发和爬虫系统中的应用展开,对Node.js在大型项目中的定位与应用做了详细的说明。
本书可用于Node.js入门,适合未接触过Node的读者以及在校的学生阅读,也适合作为高等院校和培训学校相关专业的师生教学参考。
目录
第1章 基础知识 1
1.1
Node是什么 1
1.1.1
Node与JavaScript 1
1.1.2
runtime和VM 2
1.2
Node的内部机制 3
1.2.1
何为回调 3
1.2.2
同步/异步和阻塞/非阻塞 4
1.2.3
单线程和多线程 6
1.2.4
并行和并发 7
1.3 事件循环(Event
loop) 8
1.3.1
事件与循环 8
1.3.2
Node中的事件循环 9
1.3.3
process.nextTick 13
1.4 总结 16
1.5 参考资源 16
第2章 常用模块 17
2.1
Module 17
2.1.1
JavaScript的模块规范 17
2.1.2
require及其运行机制 18
2.1.3
require的隐患 20
2.1.4
模块化与作用域 20
2.2
Buffer 22
2.2.1
Buffer的构建与转换 23
2.2.2
Buffer的拼接 24
2.3
File System 26
2.4
HTTP服务 30
2.4.1
创建HTTP 服务器 30
2.4.2
处理HTTP请求 32
2.4.3
Response对象 34
2.4.4
上传数据 35
2.4.5
HTTP客户端服务 38
2.4.6
创建代理服务器 39
2.5
TCP服务 40
2.5.1
TCP和Socket 41
2.5.2
创建TCP服务器 41
2.6 更安全的传输方式——SSL 42
2.6.1
什么是SSL 43
2.6.2
SSL原理 43
2.6.3
对称加密与非对称加密 44
2.6.4
关于CA 45
2.6.5
创建HTTPS服务 45
2.7
WebSocket 48
2.7.1
保持通话 48
2.7.2
为什么要有WebSocket 49
2.7.3
WebSocket与Node 50
2.8
Stream 50
2.8.1
Stream 的种类 50
2.8.2
ReadLine 53
2.8.3
自定义Stream 54
2.9
Events 55
2.9.1
事件和监听器 55
2.9.2
处理error事件 56
2.9.3
继承Events模块 57
2.10
多进程服务 58
2.10.1
child_process模块 58
2.10.2
spawn 58
2.10.3
fork 59
2.10.4
exec和execFile 60
2.10.5
各方法之间的比较 62
2.10.6
进程间通信 64
2.10.7
Cluster 65
2.11
Process对象 66
2.11.1
环境变量 67
2.11.2
方法和事件 67
2.11.3
一个例子:修改所在的时区 68
2.12
Timer 70
2.12.1
常用API 70
2.12.2
定时器中的this 71
2.13
小结 72
2.14
引用资源 72
第3章 用ES6来书写Node 73
3.1 新时代的EMCAScript 73
3.1.1
JavaScript的缺陷 73
3.1.2
Node对新标准的支持 74
3.1.3
使用nvm管理Node版本 75
3.2 块级作用域 75
3.2.1
ES5中的作用域 75
3.2.2
let关键字 77
3.2.3
const关键字 78
3.3 数组 78
3.3.1
find()和findIndex() 79
3.3.2
from()方法 79
3.3.3
fill()方法 81
3.3.4
数组的遍历 81
3.3.5
TypedArray 82
3.4 函数 82
3.4.1
参数的默认值 82
3.4.2
Spread运算符 83
3.4.3
箭头函数 83
3.4.4
箭头函数的陷阱 86
3.5
Set和Map 87
3.5.1
Set和WeakSet 87
3.5.2
Map和WeakMap 88
3.6
Iterator 89
3.6.1
Java中的Iterator 89
3.6.2
ES6中的Iterator 89
3.6.3
Iterator的遍历 90
3.7 对象 91
3.7.1
新的方法 91
3.7.2
对象的遍历 92
3.8 类 93
3.8.1
属性和构造函数 94
3.8.2
类方法 94
3.8.3
__proto__ 95
3.8.4
静态方法 96
3.9 类的继承 96
3.9.1
ES5中的继承 96
3.9.2
ES6中的继承 98
3.9.3
Node中的类继承 100
3.10
ES6的模块化标准 101
3.11
使用babel来转换代码 102
3.12
小结 106
3.13
引用资源 106
第4章 书写异步代码 107
4.1 异步操作的返回值 108
4.2 组织回调方法 108
4.2.1
回调与CPS 108
4.2.2
使用async模块简化回调 110
4.3 使用Promise 112
4.3.1
Promise的历史 112
4.3.2
Promise是什么 113
4.3.3
ES2015中的Promise 114
4.3.4
Promise的常用API 116
4.3.5
使用Promise组织异步代码 119
4.3.6
第三方模块的Promise 120
4.4
Generator,一种过渡方案 122
4.4.1
Generator的使用 122
4.4.2
Generator函数的执行 123
4.4.3
Generator中的错误处理 126
4.4.4
用Generator组织异步方法 127
4.4.5
Generator的自动执行 128
4.5 回调的终点——async/await 131
4.5.1
async函数的概念 131
4.5.2
await关键字 133
4.5.3
在循环中使用async方法 135
4.5.4
async和await小结 136
4.5.5
async 函数的缺点 137
4.6 总结 138
4.7 引用资源 139
第5章 使用Koa2构建Web站点 140
5.1
Node Web框架的发展历程 140
5.1.1
Connect 140
5.1.2
Express 141
5.1.3
Koa 141
5.2 内容规划 142
5.2.1
需求分析 142
5.2.2
技术选型 142
5.3
Koa入门 143
5.3.1
Koa1.x 与Koa2 143
5.3.2
context对象 144
5.4
middleware 148
5.4.1
中间件的概念 148
5.4.2
next方法 150
5.4.3
中间件的串行调用 151
5.4.4
一个例子——如何实现超时响应 152
5.5 常用服务的实现 154
5.5.1
静态文件服务 154
5.5.2
路由服务 155
5.5.3
数据存储 156
5.5.4
文件上传 160
5.5.5
页面渲染 163
5.6 构建健壮的Web应用 165
5.6.1
上传文件验证 166
5.6.2
使用Cookie进行身份验证 167
5.6.3
使用Session记录会话状态 170
5.7 使用Redis进行持久化 173
5.7.1
Node和Redis的交互 173
5.7.2
CURD操作 174
5.7.3
使用Redis持久化session 176
5.7.4
Redis在Node中的应用 179
5.8
Koa源码剖析 180
5.8.1
Koa的启动过程 180
5.8.2
中间件的加载 181
5.8.3
listen()方法 184
5.8.4
next()与return next() 185
5.8.5
关于Can’t set headers after they are sent. 186
5.8.6
Context对象的实现 187
5.8.7
Koa的优缺点 189
5.9 网站部署 190
5.9.1
本地部署 190
5.9.2
部署在云服务主机上 191
5.9.3
通过GitHub pages来部署 193
5.10
总结 194
5.11
引用资源 194
第6章 爬虫系统的开发 195
6.1 爬虫技术概述 196
6.2 技术栈简介 196
6.2.1
request.js 196
6.2.2
cheerio 197
6.2.3
消息队列 199
6.3 构建脚手架 199
6.3.1
选择目标网站 199
6.3.2
分析URL结构 200
6.3.3
构建HTTP 请求 200
6.3.4
解析页面元素 201
6.4 进行批量爬取 203
6.4.1
使用递归和定时器 203
6.4.2
多进程并行 205
6.5 爬虫架构的改进 206
6.5.1
异步流程控制 206
6.5.2
回到最初的目标 206
6.5.3
多进程模型的缺陷 208
6.6 进程架构的改进 208
6.6.1
生产/消费模型 208
6.6.2
生产者的实现 209
6.6.3
消费者的实现 211
6.7 反爬虫处理 213
6.7.1
爬虫的危害 213
6.7.2
识别一个爬虫 213
6.7.3
针对爬虫的处理 214
6.8 总结 216
6.9 引用资源 216
第7章 测试与调试 217
7.1 单元测试 218
7.1.1
使用Assert模块 218
7.1.2
Jasmine 219
7.1.3
Ava.js——面向未来 224
7.2 测试现有代码 227
7.3 更高维度的测试 228
7.3.1
基准测试 228
7.3.2
集成测试 229
7.3.3
持续集成 229
7.4 调试Node应用 231
7.4.1
语言和IDE 232
7.4.2
使用node-inspector 233
7.4.3
使用v8-inspector 234
7.4.4
使用IDE进行调试 236
7.4.5
cpu profiling 237
7.5 总结 239
7.6 引用资源 239
第8章 Node中的错误处理 240
8.1
Error模块 241
8.2 错误处理的几种方式 241
8.3 被抛弃的Domain 243
8.3.1
Domain模块简介 243
8.3.2
Domain原理 247
8.3.3
Domain中间件 249
8.3.4
Domain的缺陷 249
8.4
ES6中的错误处理 250
8.4.1
Promise 250
8.4.2
Generator 250
8.4.3
async函数 251
8.5
Web服务中的错误处理 251
8.5.1
针对每个请求的错误处理 251
8.5.2
Express中的错误处理 252
8.5.3
Koa中的错误处理 252
8.6 防御式编程与Let it
crash 253
8.7 总结 256
8.8 引用资源 256
附录A 进程、线程、协程 257
A.1 从操作系统说起 257
A.2
Node中的协程 258
附录B Lua语言简介 259
B.1
Lua中的数据类型 259
B.2 定义一个函数 260
B.3
Lua中的协程 261
附录C 从零开发一个Node
Web框架 263
C.1 框架的雏形 263
C.2 框架的完善 264
C.3 总结 268
附录D MongoDB和Redis简介 269
D.1
NoSQL 269
D.2
MongoDB简介 269
D.3
Redis简介 271
附录E 使用Docker来实现虚拟化 274
E.1
Docker的一些常用命令 274
E.2
Redis服务 275
附录F npm与包管理 277
F.1
package.json常用字段 277
F.2 依赖版本的管理 278
前 言
国内Node的开发者很多都读过朴灵写的《深入浅出Node.js》(以下简称《深入浅出》)一书,笔者也不例外,笔者在2014年初第一次接触Node,最初读的几本书就包含了这本《深入浅出》,该书出版于2013年12月,距今已经差不多有4年的时间了。
对于一门高速发展的语言来说,4年算得上很长的时间了。4年前Node的版本号还在0.10.x,而时至今日,已经迎来v8.0.0的最新版本了。
Node项目始于2009年,2013年恰好处在当今(2017年)和2009年的中间节点,一门语言在诞生之初的发展总是最快的,到了现在,Node逐渐地变得稳定下来。
但即使这样,这4年中也发生了不少大事件:Node从分裂又走向了统一,ES2015标准的推出等。
那么4年后的今天,Node有了哪些改变呢?
一方面,基本的概念几乎没有改变,底层的libuv和事件循环还是原来的样子,主要模块的API也没什么大的变化。
另一方面,变动最多的大概是语法了,ECMAScript沉寂数年之后,终于推出了重量级的新版本ES2015,并且计划每年发布一个新版本。
换个角度来说,如果现在有一份使用Node最新版本写的代码,拿给还在使用0.10的开发者看,最大可能是对里面各种奇怪的关键字和语法感到疑惑。这本身就说明了Node发生了如此大的变动。
在笔者看来,Node的发展进入了平台期,这意味着在一段时间内,Node将维持现有的模样,或许会增加或修改一些语法,底层的V8也可能做一些大幅度的改进,但代码的基本结构不会有大的变动。
Node的发展大致分为几个阶段:
? 第一个阶段:从诞生到分裂,大致5年的时间。
? 第二个阶段:从与io.js合并到ES2015标准正式落地,只有不到半年的时间。
? 第三个阶段:从v6.0.0全面支持ES2015至今,Node较大的更新都是围绕着新的ECMA201x标准展开的。
所有的新与旧都是相对的,虽然在目前来看,本书记述的内容还算是比较新的,无论是ES201x的使用,还是Koa2框架的介绍,都属于同类书中较少涉及的领域,但要是再过几年的时间,本书的内容也会变得过时。
本书定位
关于本书的定位,笔者着实费了很大的脑筋,出版社老师建议我写一本入门书,当我知道的时候其实内心是很犹豫的:一方面,Node的入门书籍市面上已经很多了,随便翻开一本,不论是里面的内容还是章节编排都大同小异;另一方面,入门书反而是最难写出水平的,因为作者们大多已经有了相关领域的编程经验,那样就很难站在入门者的角度来进行写作。
经过考虑之后,我决定写一本《新时期的Node.js入门》,一方面能够让本书立足于最新的技术潮流,另一方面对于ES201X又或者是Koa2来说,它们诞生的时间不长,笔者也不敢说自己对这些新的技术和标准已经有了丰富的编程经验(之前使用最多的还是ES5语法和Express),正好也能站在一个入门者的角度来审视这些新技术。
本书的定位是一本新时期的Node入门书,关于“新”在哪里?一方面是内容的“新”,新的标准已经出现,怎么能够停滞不前!ES2015带来了不少新的语言特性,它让之前需要花不少工夫才能解决的问题变得轻而易举。另一方面,本书不想重复介绍同类书籍已经反复介绍的内容,例如Express框架的使用,在市面上翻开任意一本Node的入门书籍,都会不厌其烦地向读者教授Express的各种用法,作为代替,本书推荐了Koa这一框架作为入门介绍,它更贴近新标准。
除了“如何使用”之外,本书还会兼顾Node底层的原理,读者大可在第一遍时跳过这些内容,当对Node有了一个大概的掌握后,会自然而然地想去了解其背后的原理。
关于本书内容
本书不是一本ES2015或者更新标准的说明书,也不想让内容停留在介绍各种模块的API罗列上。
第1章讲解Node的运行机制,主要是底层的一些实现和通用的原理,可能需要一些操作系统的知识。
第2章介绍了通用的模块和使用方法,是真正的入门章节。
第3章专注于新的ECMAScript标准以及Node对其的支持。
第4章主要介绍如何更好地组织和书写异步代码,采用循序渐进的方式介绍了各种解决方案的优劣之处。
第5章使用Koa2框架来开发一个Web应用,涉及Web开发的各方面,例如路由处理、Session、页面渲染、数据存储等。
第6章介绍了如何使用Node来开发一个爬虫系统。
第7章介绍常用的测试方法以及调试Node应用的技巧。
第8章介绍了Node中错误处理的相关知识。
附录A介绍进程、线程和协程的概念,属于拓展的背景知识。
附录B Lua语言简介,Lua几乎可以认为是某些概念的最佳实现,例如协程。
附录C从零开发了一个玩具式的Web框架,可以认为是对Koa的一个简单模仿,对于初学者来说,这应该是一个理解Node Web原理的好方法。
附录D MongoDB和Redis简介。
附录E使用Docker来实现虚拟化。
附录F介绍了使用npm来进行包管理的一些小技巧。
本书的每个章节都是环环相扣的,每一章讲述的内容都多多少少地被其他章节使用到,建议读者循序渐进地阅读(第1章可以放到最后)。
循序渐进不仅仅体现在章节安排上,在系统的实现上也是如此,以第6章爬虫的开发为例,从糟糕的代码设计开始,一步步地进行改进,最后达到比较完善的状态。
那些糟糕的代码大部分都是在笔者还是初学者时写的,笔者很庆幸自己还能留着这些代码,它们不仅见证了笔者本人对Node的认识过程,也见证了Node的发展历史。
关于本书中的代码
所有的源代码都可以在https://github.com/Yuki-Minakami/BookExample上找到,它们都经过了充分的测试。
本书中,除了Node编写的示例代码外,还会穿插一些其他语言(例如Java)的代码,这是为了通过和其他语言的对比让读者更好地理解Node中的特性。
笔者使用的电脑环境为 Mac OSX 10.11,本书中出现的代码绝大多数都是平台无关的,有一些代码在Windows环境下运行会出现问题或者不能在Windows下运行,本书也做了相应的标注和提示。读者在阅读本书的时候,也建议打开自己的电脑,第一时间把代码写在文本编辑器或者IDE中。
本书面向的读者
就像标题所说的,本书是一本入门书,适合在校的学生以及未接触过Node的读者阅读。如果读者有其他语言(例如Java)的编程经验,那么读起来可能会轻松一些,如果有使用JavaScript的经验就再好不过了。
如何学习Node
学习一门编程语言的最好办法,就是将其运用在实际的项目当中,但对于大多数开发者,尤其是自己目前的工作与Node无关时,想找到合适的项目并不容易,大多数人做的还只是非常简单的个人项目,例如一个TODO List,复杂一点的比如一个博客网站,这些都算不上什么复杂的项目,从里面得到的经验也少得可怜。
那些能处理高并发、拥有各种多进程架构的项目不是每个人都有机会做,那么到哪里去找有一些难度的Node项目练手呢?
那就只能把目光投向GitHub了,使用GitHub的搜索功能来寻找一些企业级的Node应用,如果感兴趣的话就试着提交代码,为开源项目贡献代码通常是一个不错的加分项。
虽然有点王婆卖瓜,但笔者认为本书第7章的项目还是有一定的复杂度的,针对多进程和分布式的扩展还有很大的想象空间,读者可以借助GitHub参与到共同开发上来。
名称约定
为了便于区分,JavaScript在本书中特指对ECMAScript的实现,除非特别注明,那么它代表了ES5的标准,并且同时适用于浏览器JavaScript和Node。当有些代码和概念特指在浏览器端运行的JavaScript时,我们一律使用“前端JavaScript”来称呼。
当使用ECMAScript这一称谓(例如ES2017)时,大多数是谈论标准内容,不涉及具体的实现。
纠错
笔者毕竟能力有限,在出版本书的时候可能有没有注意到的错误,例如代码运行出错、概念上的不正确等,如果读者有相关的发现,请以“××章××小结代码/内容错误”为标题发邮件至笔者的邮箱[email protected]。
致谢
首先要特别感谢的是出版社的夏毓彦编辑,是他让我有机会梳理迄今为止对Node的心得,然后得以出版。
另一方面还要感谢我的母亲,当我第一次将自己准备写书的想法告诉她时,不出意外地,她开始怀疑起我的水平来,“就你还想出书?可不要误人子弟啊”。
正是这句话,不断提醒我对内容进行反复修改和验证。因为我意识到这和平时的博客文章不同,是更加严肃,并且对错误的容忍更低的作品。虽然她没有编程相关的经验,但我还是准备将第一本样书送给她,希望她能够阅读。
著者
2017年12月
评论
还没有评论。