Node的异步编程
- 如何响应一次性事件
- 如何处理重复性事件
- 如何让异步逻辑顺序执行
Node功能的组织和重用
- Node模块
1. require
require
加载模块时是同步的。
exports
只是对module.exports
的一个全局引用,最初被定义为一个可以添加属性的空对象,所以exports.myFunc
只是module.exports.myFunc
的简写,最终导出的是后者。
注意:Node
不允许重写exports
,也即不能直接把变量赋值给exports
;module.exports
可以对外提供单个变量、函数或者对象。如果你创建了一个既有exports又有module.exports的模块,那它会返回module.exports,而exports会被忽略。
2. node_modules
要求模块在文件系统中使用相对路径存放,对于组织程序特定的代码很有帮助,但对于想要在程序间共享或跟其他人共享代码却用处不大。Node中有一个独特的模块引入机制,可以不必知道模块在文件系统中的具体位置。这个机制就是使用node_modules目录。
- 模块查找
用环境变量NODE_PATH可以改变Node模块的默认路径。如果用了它,NODE_PATH在Windows中应该设置为用分号分隔的目录列表,在其他操作系统中用冒号分隔
3. 模块是目录
如果模块是目录,在模块目录中定义模块的文件必须被命名为index.js,除非你在这个目录下一个叫package.json的文件里特别指明。要指定一个取代index.js的文件,package.json文件里必须有一个用JavaScript对象表示法(JSON)数据定义的对象,其中有一个名为main的键,指明模块目录内主文件的路径。
异步编程技术
回调:回调通常用来定义一次性响应的逻辑。
- 回调是一个函数,它被当做参数传给异步函数,它描述了异步操作完成之后要做什么
- 最好限制一下回调的嵌套层级
- 减少由if/else引起的嵌套:尽早从函数中返回
- Node中的大多数内置模块在使用回调时都会带两个参数:第一个是用来放可能会发生的错误的,第二个是放结果的。错误参数经常被缩写为er或err
事件发射器:事件监听本质上也是一个回调,不同的是,它跟一个概念实体(事件)相关联。
- 事件发射器会触发事件,并且在那些事件被触发时能处理它们
- 事件发射器通常用来定义重复派发的异步逻辑
闭包:用闭包控制程序的状态
- Node的事件轮询会跟踪还没有完成的异步逻辑。只要有未完成的异步逻辑,Node进程就不会退出
- 程序的变量可能会出现意想不到的变化
- 用JavaScript闭包可以“冻结”外部变量到函数内部的本地变量
异步逻辑的顺序化
- 流程控制:让一组异步任务顺序执行的概念被Node社区称为流程控制
- 串行:需要一个接着一个做的任务叫做串行任务
- 并行:任务彼此之间开始和结束的时间并不重要,但在后续逻辑执行之前它们应该全部做完
1. 使用和实现串行化流程控制
- 用回调让任务顺序执行
- 用setTimeout模拟
- Nimble流程控制工具
require('nimble')
4. 使用和实现并行化流程控制
为了让异步任务并行执行,仍然是要把任务放到数组中,但任务的存放顺序无关紧要。每个任务都应该调用处理器函数增加已完成任务的计数值。当所有任务都完成后,处理器函数应该执行后续的逻辑。