플로우란 무엇인가요? 흐름을 이해하는 방법? 다음 기사는 Nodejs의 스트림에 대한 심층적인 이해를 제공할 것입니다. 도움이 되기를 바랍니다.
stream은 EventEmitter를 상속받은 추상 데이터 인터페이스입니다. 데이터를 보내고 받을 수 있습니다. 그 본질은 아래와 같이 데이터 흐름을 만드는 것입니다.
Stream은 Node에서 고유한 개념이 아니라 운영 체제입니다. Linux |에서 가장 기본적인 동작 방식은 Stream인데 Node 레벨에서 캡슐화되어 해당 API를 제공합니다
먼저 다음 코드를 사용하여 약 400MB 정도의 파일을 생성합니다. [관련 튜토리얼 권장 사항: nodejs video tutorial]
readFile을 사용하여 읽을 때 다음 코드
가 정상입니다. 시작할 때 이 서비스는 약 10MB의 메모리를 차지합니다
curl http://127.0.0.1:8000
을 사용하여 요청을 시작하면 메모리는 약 420MB가 됩니다. curl http://127.0.0.1:8000
发起请求时,内存变为了 420MB 左右,和我们创建的文件大小差不多
改为使用使用 stream 的写法,代码如下
再次发起请求时,发现内存只占用了 35MB 左右,相比 readFile 大幅减少
如果我们不采用流的模式,等待大文件加载完成在操作,会有如下的问题:
总结来说就是,一次性读取大文件,内存和网络都吃不消
我们读取文件的时候,可以采用读取完成之后在输出数据
上述说到 stream 继承了 EventEmitter 可以是实现监听数据。首先将读取数据改为流式读取,使用 on("data", ()⇒{})
接收数据,最后通过 on("end", ()⇒{})
最后的结果
有数据传递过来的时候就会触发 data 事件,接收这段数据做处理,最后等待所有的数据全部传递完成之后触发 end 事件。
数据是从一个地方流向另一个地方,先看看数据的来源。
http 请求,请求接口来的数据
console 控制台,标准输入 stdin
file 文件,读取文件内容,例如上面的例子
在 source 和 dest 中有一个连接的管道 pipe,基本语法为 source.pipe(dest)
Change 스트림 쓰기를 사용하기 위한 코드는 다음과 같습니다
요청을 다시 시작해보니 메모리가 약 35MB 정도만 차지하는 것을 발견했는데, 이는 readFile
일시적으로 너무 많은 메모리가 사용되어 시스템이 충돌합니다
CPU 작동 속도가 제한되어 여러 서비스를 제공합니다. 대용량 파일은 용량이 너무 크고 로딩 시간도 오래 걸립니다어떻게 하면 조금씩 할 수 있나요?
파일을 읽을 때 읽기가 완료된 후 데이터를 출력할 수 있습니다
🎜🎜🎜위에서 언급했듯이 스트림은 EventEmitter를 상속하여 모니터링 데이터를 구현합니다. 먼저 읽기 데이터를 스트리밍 읽기로 변경하고on("data", ()⇒{})
를 사용하여 데이터를 수신하고 마지막으로 on("end", ()⇒를 사용합니다. { })
최종 결과🎜🎜🎜🎜데이터가 전송되면 데이터 이벤트가 발생하고, 처리를 위해 데이터를 수신하며, 데이터가 모두 전송된 후 종료 이벤트가 발생합니다. 🎜source.pipe(dest)
, Source입니다. 및 dest는 파이프를 통해 연결되므로 데이터가 소스에서 대상으로 흐를 수 있습니다.🎜🎜위 코드처럼 데이터/종료 이벤트를 수동으로 모니터링할 필요가 없습니다.🎜🎜파이프를 사용할 때는 소스를 읽을 수 있어야 한다는 엄격한 요구 사항이 있습니다. 스트림, 그리고 대상은 쓰기 가능한 스트림입니다🎜🎜 정확히 흐르는 데이터가 무엇인가요? 코드에서 청크란 무엇입니까? 🎜🎜🎜갈 곳—dest🎜🎜🎜stream 세 가지 일반적인 출력 방법🎜🎜🎜🎜콘솔 콘솔, 표준 출력 stdout🎜🎜🎜🎜http 요청, 인터페이스 요청의 응답
파일 파일, 쓰기 파일
읽을 수 있는 스트림은 데이터를 제공하는 소스의 추상화
모든 Readables는 stream.Readable 클래스에 의해 정의된 인터페이스를 구현합니다
?
Readable 스트림에는 청크 데이터의 흐름 모드를 결정하는
flowing 모드와 pause 모드
의 두 가지 모드가 있습니다. 자동 흐름과 수동 흐름 Flowture: 흐름 모드를 나타냅니다. false: 일시 중지 모드를 나타냅니다. null: 초기 상태
데이터는 하위 레이어에서 자동으로 읽어와 흐름 현상을 형성하고 이벤트를 통해 애플리케이션에 제공됩니다.
데이터 이벤트를 수신하여 이 모드로 들어갈 수 있습니다.stream.pipe 메서드를 호출하여 Writeable에 데이터를 보냅니다
stream.resume 메서드 호출
데이터는 내부 버퍼에 축적되며 표시되어야 합니다. 데이터 블록을 읽으려면 stream.read()를 호출하세요
읽기 가능한 스트림이 초기 상태에 있습니다. //TODO: 온라인 공유와 일치하지 않음
- 监听 data 事件 - 调用 stream.resume 方法 - 调用 stream.pipe 方法将数据发送到 Writable
- 移除 data 事件 - 调用 stream.pause 方法 - 调用 stream.unpipe 移除管道目标
구현 원칙
A 캐시는 스트림에 유지됩니다. 읽기 메소드가 호출되면 하위 레이어에서 데이터를 요청해야 하는지 판단됩니다
버퍼 길이가 highWaterMark 값보다 0 이하이면 _read가 호출되어 하위 레이어에서 데이터를 가져옵니다소스 코드 링크
Writable 스트림은 데이터 쓰기 대상의 추상화는 업스트림에서 흐르는 데이터를 소비하고 쓰기 가능한 스트림을 통해 데이터를 장치에 쓰는 데 사용됩니다. 일반적인 쓰기 스트림은 로컬 디스크에 쓰는 것입니다
write를 통해 데이터 쓰기
end를 통해 데이터를 쓰고 스트림을 닫습니다. end = write + close
기록된 데이터가 highWaterMark 크기에 도달하면 Drain이 실행됩니다. 이벤트
는 ws.write(chunk)를 호출하고 false를 반환하여 현재 버퍼 데이터가 highWaterMark 값보다 크거나 같고 배수 이벤트가 트리거됨을 나타냅니다. 실제로 이는 경고 역할을 하지만 처리되지 않은 데이터는 항상 쓰기 가능한 스트림의 내부 버퍼에 백로그됩니다. 백로그가 Node.js 버퍼로 가득 찰 때까지는 강제되지 않습니다. .Interrupt
모든 쓰기 가능 항목은 stream.Writeable 클래스에 의해 정의된 인터페이스를 구현합니다.
하단 레이어에 데이터를 쓰려면 _write 메소드만 구현하면 됩니다
읽기 및 쓰기가 모두 가능한 이중 스트림. 실제로 Readable 및 Writable을 상속하는 스트림입니다. 읽기 가능한 스트림과 쓰기 가능한 스트림으로 모두 사용할 수 있습니다. 사용자 정의 이중 스트림은 Readable의 _read 메소드와 Writable의 _write 메소드를 구현해야 합니다.
net 모듈은 소켓을 만드는 데 사용할 수 있습니다. 소켓은 NodeJS의 일반적인 이중입니다. 클라이언트는 메시지를 보내는 데 사용됩니다. 읽기 스트림은 서버 메시지를 수신하는 데 사용됩니다. 두 스트림의 데이터 사이에는 직접적인 관계가 없습니다 변환 스트림사실 less()와 minifyCss()는 모두 입력 데이터에 대해 일부 처리를 한 다음 출력 데이터를 넘겨줍니다
양면 및 변형 옵션위의 예와 비교하면 스트림이 생산자와 소비자 모두에게 서비스를 제공하는 경우 Duplex를 선택하게 됩니다. 데이터에 대한 일부 변환 작업만 수행할 경우 Transform
배압 문제는 생산자-소비자 모델에서 발생합니다. 소비자 처리 속도가 너무 느립니다
예를 들어 다운로드 프로세스 중 처리 속도는 3Mb/s이고 압축 중에는 처리 속도가 3Mb/s입니다. 프로세스가 너무 느립니다. 속도가 1Mb/s입니다. 이 경우 버퍼 큐가 곧 누적됩니다. 전체 프로세스의 메모리 소비가 증가하거나 전체 버퍼가 느려지고 일부 데이터가 손실됩니다. . 배압 처리란 무엇입니까?
배압 처리는 위쪽으로 "울어내는" 과정으로 이해될 수 있습니다.
압축 프로세스에서 버퍼 데이터 스퀴즈가 임계값을 초과한 것을 발견하면 다운로드 처리에 "울어줄" 것입니다. 너무 바빠서 더 이상 게시하지 마세요
메시지를 받은 후 다운로드 처리가 일시 중지되어 데이터 전송이 중단됩니다한 프로세스에서 다른 프로세스로 데이터를 전송하는 다양한 기능이 있습니다. Node.js에는 .pipe()라는 내장 함수가 있으며 궁극적으로 이 프로세스의 기본 수준에는 두 가지 관련 없는 구성 요소가 있습니다: 데이터 소스와 소비자
.pipe()가 소스에서 호출하면 전송할 데이터가 있음을 소비자에게 알립니다. 파이프라인 기능은 이벤트 트리거에 적합한 백로그 패키지를 설정합니다
데이터 캐시가 highWaterMark를 초과하거나 쓰기 대기열이 사용 중이면 .write()가 false를 반환합니다파이프의 배압 처리를 볼 수 있습니다.
데이터를 청크별로 나누고 청크가 통과하면 씁니다. 큐가 너무 크거나 사용량이 많으면 읽기가 일시 중지됩니다큐가 비어 있으면 데이터를 계속 읽으세요노드 관련 지식을 더 보려면nodejs 튜토리얼
을 방문하세요!위 내용은 Stream in Node에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!