文章目录
严格来说,一切动作都是事件,这就是事件驱动的思想
事件驱动
就是把网络请求、I/O操作看作是事件,在程序启动的时候,便进入事件循环,不断遍历执行事件队列中产生的事件。而在执行的过程中又产生新的事件,这就是事件循环。
事件驱动原理:观察者模式(事件发布/订阅模式)
特点
- 事件驱动
- 非阻塞式IO
- 单线程
- 无法利用多核CPU
- 错误会引起整个应用退出
- 大量计算占用CPU会导致无法继续调用异步IO
- 同前端WebWorker,node通过child_process来将计算分发给子进程
多进程架构
创建子进程:
- spawn:启动一个子进程来执行命令
- exec:启动要给子进程来执行命令,与spawn不同的是,它有一个回调函数获知子进程的状况
- execFile:启动一个子进程来执行可执行文件
- fork:与spawn类似,不同点在于它创建时只需要指定要执行的JavaScript文件模块即可
1 | const cp = require('child_process') |
进程之间的通信
1 | // main.js |
通信原理
IPC Inter-Process Communication,进程间通信。
Node中实现IPC通道的是管道(pipe)技术。具体细节由libux提供
Stream 流
Reference
Readable Stream
Event
- data
- end
- error
- close
- readable,消费者监听
readable
不会消费数据,需要手动调用read(size)
方法,只要数据到达缓存池就会触发一次readable
事件
Methods
- pipe(), unpipe()
- read(), unshift(), resume()
- pause(), isPaused()
- setEncoding()
状态
可读流有两种状态:
- 暂停状态
- 流动状态
当一个可读流处于暂停状态,可以使用
read()
状态按需读取数据,而对于一个流动模式的可读流,可以通过监听来处理数据
通过增加一个data
回调函数可以把暂停模式的流切换到流动模式,移除data
事件回调之后会把流从流动模式切换回暂停模式
可以通过pause()
与resume()
方法手动切换这两个状态
在可读流中,数据的流向不是直接流向消费者,而是先push
到一个缓存池,缓存池有一个水位标志hightWatermark
,超过这个标志,push
就会返回false
。
一般下面两种情况可以使得push
返回false
- 消费者主动使用了
pause()
- 当
push
的速度大于消费的速度时候
暂停模式也有三个状态:
- _readableState.flow = null,暂时没有消费者
- _readableState.flow = false,主动触发了pause
- _readableState.flow = true,流动模式
Writable Stream
Event
- drain
- finish
- error
- close
- pipe / unpipe
Methods
- write()
- end()
- cork(), uncork()
- setDefaultEncoding()