Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node.js: Foundmental #89

Open
xvno opened this issue May 15, 2020 · 2 comments
Open

Node.js: Foundmental #89

xvno opened this issue May 15, 2020 · 2 comments

Comments

@xvno
Copy link
Owner

xvno commented May 15, 2020

Refs

Current version Node.js v14.2.0

@xvno
Copy link
Owner Author

xvno commented May 15, 2020

Buffer

Class methods

Buffer.xxx()

  • Buffer.alloc(size[, fill[, encoding]])
  • allocUnsafe(size)
  • allocUnsafeSlow(size)
  • byteLength(string[, encoding])
  • compare(buf1, buf2)
  • concat(list[, totalLength])
  • from(array)
  • from(arrayBuffer[, byteOffset[, length]])
  • from(buffer)
  • from(object[, offsetOrEncoding[, length]])
  • from(string[, encoding])
  • isBuffer(obj)
  • isEncoding(encoding)

Instance methods

  • buf[index]
  • buf.buffer
  • buf.tyteOffset
  • buf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])
  • buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
  • buf.entries()
  • buf.equals(otherbuffer)
  • buf.toString([encoding[, start[, end]]])
  • buf.toJSON()
  • buf.write(string[, offset[, length]][, encoding])
  • buf.subarray([start[,end]])
  • buf.slice([start[, end]])

Module methods

  • buffer.transcode(source, fromEnc, toEnc)

@xvno
Copy link
Owner Author

xvno commented May 15, 2020

Stream

const stream = require('stream');

Types of Streams

  1. Writable: fs.createWriteStream(), client side HTTP request, server side HTTP response, fs write streams, zlib streams, zlib streams, TCP.sockets, Child Process stdin, process.stdout, process.stderr;
  2. Readable: fs.createReadStream(),
  3. Duplex: net.Socket
  4. Tranform

Object Model

Node.js API 创建的所有stream本身操作都作用于String对象和Bufer对象(or Uint8Array).

Buffering

Writable 和 Readable streams 都把数据存储在内部buffer中, 可以分别使用 writable.writableBufferreadable.readableBuffer获取.

被Buffer的数据量是由highWaterMark来决定的, 它是该stream构造函数的参数. 单位为Byte.

  1. 对于Readable来说调用stream.push(chunk)就会把数据buffer进stream中. 如果消费者没有调用stream.read(), 数据便停在内部存储中.

内部存贮中的数据达到上限 highWaterMark 后, stream便会停止读取源数据直到其中数据被消费.

  1. 对于 Writable 来说, 调用 stream.write(chunk) 便会吧数据存入内部存储中(inner buffer). 如果internal write buffer 低于 highWaterMark, 调用 writable.write(chunk) 会返回 true, 如果达到或者超出, 则会返回false. Writable 会暴露 write(chunk)end() 方法来写入数据.

  2. stream.pipe()用来把发送数据的速率适配接收方能接受的速率.

  3. Duplex 和 Transform 既是Readable 又是 Writable, 每一方维持一个内部buffer.

  4. Readable & Writable都使用 EventEmitter 的API来完成操作

API for Stream Consumers

const http = require('http');
const server = http.createServer((req, res) => {
  // `req` is an http.IncomingMessage, which is a Readable Stream.
  // `res` is an http.ServerResponse, which is a Writable Stream.

  let body = '';
  // Get the data as utf8 strings.
  // If an encoding is not set, Buffer objects will be received.
  req.setEncoding('utf8');

  // Readable streams emit 'data' events once a listener is added.
  req.on('data', (chunk) => {
    body += chunk;
  });

  // The 'end' event indicates that the entire body has been received.
  req.on('end', () => {
    try {
      const data = JSON.parse(body);
      // Write back something interesting to the user:
      res.write(typeof data);
      res.end();
    } catch (er) {
      // uh oh! bad json!
      res.statusCode = 400;
      return res.end(`error: ${er.message}`);
    }
  });
});

server.listen(1337);

Writable Streams

  • HTTP requests, on the client
  • HTTP responses, on the server
  • fs write streams
  • zlib streams
  • crypto streams
  • TCP sockets
  • child process stdin
  • process.stdout, process.stderr

所有的 Writable streams 都实现了stream.Writable 这个类所定义的接口.

Class: stream.Writable

Events:

  • close: stream 或它的源文件被关闭时. 之后不会再有事件和操作.
  • drain: 当stream能够继续写的时候, 该事件迸发
  • finish: stream.end() 后迸发
  • pipe: 当readable.pipe(writer)时, writer上迸发
  • unpipe: 当readable.unpipe(writer)时, writer上迸发

Methods

  • cork()
  • uncork()
  • destroy()
  • end([chunk[, encoding]][, callback])
  • setDefaultEncoding(encoding)
  • write(), writable.writable === true if writable can write

Readable Streams

  • HTTP responses, on the client
  • HTTP requests, on the server
  • fs read streams
  • zlib streams
  • crypto streams
  • TCP sockets
  • child process stdout and stderr
  • process.stdin

两种模式 三种状态

  1. paused: 调用stream.read()获取数据
  2. flowing

重要观念: Readable直到提供了消费函数或忽略函数才会产生数据. 如果消费函数作废或移除, Readable便会停止.

为了向后兼容的原因, 移除 data事件监听函数不会自动暂停stream产生数据. 同样的, 如果有pipe下游, 调用stream.pause() 并不能保持暂停(一旦下游drain了并请求更多数据)

如果Readable切换成flowing模式, 但并没有提供有效的消费函数, 那么数据就丢了: 例如, 没有提供data事件处理函数, 而直接调用了stream.resume()

所有的Readable stream 默认模式paused, 可以用以下三种方法来切换成flowing模式:
  1. 'data' event handler
  2. 调用 stream.resume()
  3. stream.pipe(writer)
再次切换回paused模式可以使用一下两种方法:
  1. 没有pipe下游, 调用stream.pause()
  2. 移除pipe下游, 多个下游可以用stream.unpipe()来完成.
三种状态 readable.readableFlowing = {null, false, true}
  1. 初始状态为null,
  2. 1). 添加了data事件处理函数, 2). 调用了pipe(), 3).调用了resume 都会改为 true
  3. 在调用pause(), unpipe(), 改为false

false期间数据会积累存储到内部buffer中, 期待resume(): data事件会停止, 但是数据生成不会.

@xvno xvno pinned this issue May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant