노드 스트림에는 4가지 유형이 있습니다: 1. 읽기 가능(읽기 가능한 스트림). 콘텐츠를 반환하려면 "_read" 메서드를 구현해야 합니다. 2. 쓰기 가능(쓰기 가능 스트림), 콘텐츠를 허용하려면 "_write" 메서드를 구현해야 합니다. 3. 이중(읽기 및 쓰기 가능 스트림), "_read" 및 " 콘텐츠를 수락하고 반환하려면 _write" 메서드를 구현해야 합니다. 4. 변환(변환 스트림), 수신된 콘텐츠를 변환하고 콘텐츠를 반환하려면 "_transform" 메서드를 구현해야 합니다.
이 튜토리얼의 운영 환경: Windows 7 시스템, nodejs 버전 16, DELL G3 컴퓨터.
Stream은 Nodejs의 매우 기본적인 개념입니다. 많은 기본 모듈이 스트림을 기반으로 구현되며 매우 중요한 역할을 합니다. 동시에 흐름은 이해하기 매우 어려운 개념이기도 합니다. 이는 주로 관련 문서가 부족하기 때문입니다. 다행히도 NodeJ 초보자의 경우 이 개념을 완전히 익히기 전에 흐름을 이해하는 데 많은 시간이 걸립니다. 대부분의 NodeJ에서는 사용자의 경우 웹 애플리케이션을 개발하는 데만 사용됩니다. 스트림에 대한 이해가 부족해도 사용에 영향을 미치지 않습니다. 그러나 스트림을 이해하면 NodeJ의 다른 모듈을 더 잘 이해할 수 있으며 경우에 따라 스트림을 사용하여 데이터를 처리하면 더 나은 결과를 얻을 수 있습니다.
Stream
Stream은 Node.js에서 스트리밍 데이터를 처리하기 위한 추상 인터페이스입니다. 스트림은 실제 인터페이스가 아니라 모든 스트림을 가리키는 일반적인 용어입니다. 실제 인터페이스는 ReadableStream, WritableStream 및 ReadWriteStream입니다.
ReadableStream과 WritableStream은 모두 EventEmitter 클래스를 상속하는 인터페이스임을 알 수 있습니다(ts의 인터페이스는 병합 유형이므로 클래스를 상속할 수 있습니다).
위 인터페이스에 해당하는 구현 클래스는 각각 Readable, Writable 및 Duplex입니다.
NodeJ에는 4가지 유형의 스트림이 있습니다.
Readable Readable 스트림(ReadableStream 구현)
Writable 스트림( WritableStream 구현)
Duplex 읽기 및 쓰기 가능 스트림(Readable을 상속한 후 WritableStream 구현)
Transform 변환 스트림(Duplex 상속)
모두 구현해야 할 메서드가 있습니다.
Readable이 있어야 합니다. 구현된_ 콘텐츠를 반환하는 읽기 메서드
Writable은 콘텐츠를 허용하기 위해 _write 메서드를 구현해야 함
Duplex는 콘텐츠를 허용하고 반환하기 위해 _read 및 _write 메서드를 구현해야 함
Transform은 허용하는 _transform 메서드를 구현해야 함 콘텐츠가 변환되면
Readable
을 반환합니다. 읽기 가능은 스트림 유형입니다. 여기에는 두 가지 모드와 세 가지 상태가 있습니다.
두 가지 읽기 모드:
흐름 모드: 기본 시스템에서 데이터를 읽습니다. 버퍼가 가득 차면 EventEmitter를 통해 가능한 한 빨리 데이터를 등록된 이벤트 핸들러에 자동으로 전달합니다. 일시 중지 모드: 이 모드에서는 EventEmitter가 데이터를 적극적으로 전송하지 않습니다. 버퍼에서 데이터를 읽으려면 Readable.read() 메서드를 명시적으로 호출해야 합니다. 읽기는 EventEmitter 이벤트에 대한 응답을 트리거합니다.
세 가지 상태: Readable.read() 方法来从缓冲区中读取数据,read 会触发响应到 EventEmitter 事件。
이며 데이터 이벤트를 추가한 후에는 true가 됩니다. pause(), unpipe()가 호출되거나 backPressure가 수신되거나 readable 이벤트가 추가되면 readableFlowing</code > will은 false로 설정됩니다. </td>이 상태에서는 리스너를 데이터 이벤트에 바인딩해도 readableFlowing이 true로 전환되지 않습니다<td>. </td></tr><code>resume()을 호출하여 읽기 가능한 흐름의 readableFlowing을 true로 전환하세요.
모든 읽기 가능한 이벤트를 제거하는 것이 readableFlowing을 null로 만드는 유일한 방법입니다. 버퍼에 새로 읽을 수있는 데이터가있을 때 (캐시 풀에 삽입 된 모든 노드에 대해 트리거링) 데이터가 소비될 때마다 트리거됩니다. 매개변수는 스트림이 닫힐 때 트리거됩니다. 설명
read(size)
null을 반환하면 현재 데이터가 size보다 작다는 의미이며, 그렇지 않으면 이번에 소비된 데이터가 반환됩니다. size를 넘기지 못한다면 캐시풀에 있는 모든 데이터를 소모한다는 뜻입니다
// hwm 不会大于 1GB.
const MAX_HWM = 0x40000000;
function computeNewHighWaterMark(n) {
if (n >= MAX_HWM) {
// 1GB限制
n = MAX_HWM;
} else {
//取下一个2最高幂,以防止过度增加hwm
n--;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
n++;
}
return n;
}
로그인 후 복사
流动模式
所有可读流开始的时候都是暂停模式,可以通过以下方法可以切换至流动模式:
添加 " data " 事件句柄;
调用 “ resume ”方法;
使用 " pipe " 方法把数据发送到可写流
流动模式下,缓冲池里面的数据会自动输出到消费端进行消费,同时,每次输出数据后,会自动回调 _read 方法,把数据源的数据放到缓冲池中,如果此时缓存池中不存在数据则会直接吧数据传递给 data 事件,不会经过缓存池;直到流动模式切换至其他暂停模式,或者数据源的数据被读取完了( push(null) );
可读流可以通过以下方式切换回暂停模式:
如果没有管道目标,则调用 stream.pause() 。
如果有管道目标,则移除所有管道目标。调用 stream.unpipe() 可以移除多个管道目标。
const { Readable } = require('stream')
let count = 1000
const myReadable = new Readable({
highWaterMark: 300,
read(size) {
let chunk = null
setTimeout(() => {
if (count > 0) {
let chunkLength = Math.min(count, size)
chunk = '1'.repeat(chunkLength)
count -= chunkLength
}
this.push(chunk)
}, 500)
}
})
myReadable.on('data', data => {
console.log(data.toString())
})