Nodejs

文章目录

严格来说,一切动作都是事件,这就是事件驱动的思想

事件驱动

就是把网络请求、I/O操作看作是事件,在程序启动的时候,便进入事件循环,不断遍历执行事件队列中产生的事件。而在执行的过程中又产生新的事件,这就是事件循环。

事件驱动原理:观察者模式(事件发布/订阅模式)

特点

  • 事件驱动
  • 非阻塞式IO
  • 单线程
    • 无法利用多核CPU
    • 错误会引起整个应用退出
    • 大量计算占用CPU会导致无法继续调用异步IO
    • 同前端WebWorker,node通过child_process来将计算分发给子进程

多进程架构

创建子进程:

  1. spawn:启动一个子进程来执行命令
  2. exec:启动要给子进程来执行命令,与spawn不同的是,它有一个回调函数获知子进程的状况
  3. execFile:启动一个子进程来执行可执行文件
  4. fork:与spawn类似,不同点在于它创建时只需要指定要执行的JavaScript文件模块即可
1
2
3
4
5
6
7
8
9
10
11
12
const cp = require('child_process')

cp.spawn('node', ['worker.js'])
cp.exec('node worker.js', function(err, stdout, stderr) {
//...
})

cp.execFile('worker.js', function(err, stdout, stderr) {
//...
})

cp.fork('./worker.js')

进程之间的通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// main.js
const cp = require('child_process')
const n = cp.fork('./worker')

n.on('message', function(data) {
console.log('n:', data)
})

n.send('n->data')

// worker.js
process.on('message', function(data) {
console.log('process:', data)
})

process.send({data: 23})

通信原理

IPC Inter-Process Communication,进程间通信。
Node中实现IPC通道的是管道(pipe)技术。具体细节由libux提供

Stream 流

Reference

  1. nodejs-stream
  2. 流:你需要知道的一切

Readable Stream

Event

  1. data
  2. end
  3. error
  4. close
  5. readable,消费者监听readable不会消费数据,需要手动调用read(size)方法,只要数据到达缓存池就会触发一次readable事件

Methods

  1. pipe(), unpipe()
  2. read(), unshift(), resume()
  3. pause(), isPaused()
  4. setEncoding()

状态

可读流有两种状态:

  1. 暂停状态
  2. 流动状态

当一个可读流处于暂停状态,可以使用read()状态按需读取数据,而对于一个流动模式的可读流,可以通过监听来处理数据
通过增加一个data回调函数可以把暂停模式的流切换到流动模式,移除data事件回调之后会把流从流动模式切换回暂停模式
可以通过pause()resume()方法手动切换这两个状态

在可读流中,数据的流向不是直接流向消费者,而是先push到一个缓存池,缓存池有一个水位标志hightWatermark,超过这个标志,push就会返回false

一般下面两种情况可以使得push返回false

  1. 消费者主动使用了pause()
  2. push的速度大于消费的速度时候

暂停模式也有三个状态:

  1. _readableState.flow = null,暂时没有消费者
  2. _readableState.flow = false,主动触发了pause
  3. _readableState.flow = true,流动模式

Writable Stream

Event

  1. drain
  2. finish
  3. error
  4. close
  5. pipe / unpipe

Methods

  1. write()
  2. end()
  3. cork(), uncork()
  4. setDefaultEncoding()

实现流

分享到: