Node Stream pipe的诞生
流在Node.js中是处理流数据的抽象接口。
stream
模块提供了基础的API。使用这些API可以很容易地来构建实现流接口的对象。 Node.js里提供了很多流对象。例如http.IncomingMessage
类、fs.createReadStream
类等等。都继承流的私有属性和公有方法。 所以学习流,有助于学习Node的其他模块。
文章结构
- 简介stream
- pipe源码
stream
const EE = require('events');
const util = require('util');
function Stream() {EE.call(this);
}
util.inherits(Stream, EE);
复制代码
Stream
继承EventEmitter
。流可以是可读的、可写的,或是可读写的。Stream
分为Readable
(可读流)、Writable
(可写流)、Duplex
(可读写流)、Transform
(读写过程中可以修改和变换数据的 Duplex 流)。
pipe
Stream.prototype.pipe = function(dest, options){var source = this;source.on('data', ondata);dest.on('drain', ondrain);if (!dest._isStdio && (!options || options.end !== false)) {source.on('end', onend);source.on('close', onclose);}source.on('error', onerror);dest.on('error', onerror);source.on('end', cleanup);source.on('close', cleanup); dest.on('close', cleanup);dest.emit('pipe', source);return dest;
};
复制代码
Stream
公有方法pipe
- source是可读流:Readable。dest是可写流:Writable。
Readable.pipe(Writable)
。- Readable订阅事件:data、error、end、close。Readable接收到事件执行相应的方法。
- Writable订阅事件:drain、error、close,并发布pipe事件。Writable接收到事件执行相应的方法。
- 返回Writable。
ondata
function ondata(chunk) {if (dest.Writable) {if (false === dest.write(chunk) && source.pause) {source.pause();}}}
复制代码
- Readable订阅data事件。
- Readable触发data事件,表示读入数据。
dest.Writable
当写完时会赋值为false。- 如果读的太快,没有写完
dest.write(chunk)
返回false。 source.pause
暂停写入。- 总结:订阅data事件,触发ondata方法,如果Readable读入数据太快,来不及写入,要暂停读入数据。
ondrain
function ondrain() {if (source.Readable && source.resume) {source.resume();}}
复制代码
- Writable订阅drain事件。
- Writable触发drain事件,表示这时才可以继续向流中写入数据。
source.Readable
在读到末尾时会赋值为false。source.resume()
表示会重新触发Writable的data事件。- 总结:订阅drain事件,表示这时才可以继续向流中写入数据,调用
source.resume()
,触发Writable的data事件。
cleanup
function cleanup() {source.removeListener('data', ondata);dest.removeListener('drain', ondrain);source.removeListener('end', onend);source.removeListener('close', onclose);source.removeListener('error', onerror);dest.removeListener('error', onerror);source.removeListener('end', cleanup);source.removeListener('close', cleanup);dest.removeListener('close', cleanup);}复制代码
- 移除Writable和Readable订阅的事件。
error
function onerror(er) {cleanup();if (EE.listenerCount(this, 'error') === 0) {throw er; // Unhandled stream error in pipe.}}
复制代码
- Writable和Readable有错误是执行的方法。
options
if (!dest._isStdio && (!options || options.end !== false)) {source.on('end', onend);source.on('close', onclose);
}
复制代码
dest._isStdio
暂时没理解。- 如果不传options或者options.end不是false,给Readable订阅end和close事件。
onend
var didOnEnd = false;function onend() {if (didOnEnd) return;didOnEnd = true;dest.end();}
复制代码
- 当Readable触发end事件时,执行
dest.end()
,停止写入。
onclose
function onclose() {if (didOnEnd) return;didOnEnd = true;if (typeof dest.destroy === 'function') dest.destroy();}复制代码
- 当Readable触发close事件后,该流将不会再触发任何事件。
dest.destroy()
摧毁这个流,并发出传过来的错误。当这个函数被调用后,这个写入流就结束了。
小记
- pipe方法大白话:读东西,写东西,读快了,来不及写,暂停读,来得及写了,再读东西,再写。。。
- 流在Node.js中应用广泛,http、文件、打包工具等等。可见流的重要性。
- 学习源码,有助于理解底层的实现。
参考
- Stream
- pipe
Node Stream pipe的诞生相关推荐
- stream pipe的原理及简化源码分析
前言 在编写代码时,我们应该有一些方法将程序像连接水管一样连接起来 -- 当我们需要获取一些数据时,可以去通过"拧"其他的部分来达到目的.这也应该是IO应有的方式. -- Doug ...
- NODE Stream流总结(1)
Stream简介 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). Stream模块提供了基础的API, 使用这些API可以很容易地来构建实现流 ...
- Node 深入Stream(2)
1. Node.js 中有四种基本的流类型: Readable - 可读的流 (例如 fs.createReadStream()). Writable - 可写的流 (例如 fs.createWrit ...
- Node.js Stream(流) 简单易懂全解析
一.node.js中的流是什么 stream(流)是Node.js提供的又一个仅在服务区端可用的模块,流是一种抽象的数据结构.Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如, ...
- node随笔-数据流Stream
一. 流(stream) 在 Node.js 中是处理流数据的抽象接口(abstract interface), stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流接 ...
- Node.js: 认识流stream
流是Node.js中一个非常重要的概念, 也是Node.js之所以适用于I/O密集型场景的重要原因之一. 流是Node.js移动数据的方式,流可以是可读的和/或可写的.在Node.js中很多模块都使用 ...
- 接收大文件流_一文搞定 Node.js 流 (Stream)
stream(流)是一种抽象的数据结构.就像数组或字符串一样,流是数据的集合. 不同的是,流可以每次输出少量数据,而且它不用存在内存中. 比如,对服务器发起 http 请求的 request/resp ...
- Node.js之Stream
Node.js之Stream 例子1 Steam-流 例子2\3 管道 Stream对象的原型链 Stream的分类 自创流 例子1 const fs = require("fs" ...
- node.js使用手册_权威的Node.js手册
node.js使用手册 Note: you can get a PDF, ePub, or Mobi version of this handbook for easier reference, or ...
- base64 转二进制_一篇文章弄明白Node.js与二进制数据流
1 认识二进制数据 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二", ...
最新文章
- Intel SGX Remote Attestation实例代码安装和执行,笔记
- Google Chrome 增加拦截恶意下载的支持
- HashSet源码分析 jdk1.6
- 《多元统计分析》学习笔记之主成分分析
- 在使用ToolBar + AppBarLayout,实现上划隐藏Toolbar功能,遇到了一个坑。
- Java基础——类加载机制
- 倒N字形排列java_Java排序8大算法实现
- 如何查看电脑是几核几线程
- vsync信号产生与分发
- SQL中GROUP BY的理解
- 设计模式--适配器(Adapter)
- Struts2 文件上传 文件类型 大小过滤
- 虫师Selenium2+Python_11、自动化测试项目实战
- javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
- python将图片转为矢量图
- java学习(方法)
- 前端框架 ng 环境配置
- PHP 阿里云实人认证
- 在配有通道的计算机系统中,用户程序需要输出时,引起的中断是,计算机系统结构自考2009年7月真题...
- K8S 快速入门(十六)实战篇:StorageClass(存储类)
热门文章
- 传统高斯模糊与优化算法(附完整C++代码)
- 图像去雾:基于暗通道的去雾算法 - 附代码
- 【pytorch】RuntimeError: 1only batches of spatial targets supported (3D tensors) but got targets of si
- 从零基础入门Tensorflow2.0 ----八、43. 自定义流程分布式
- pycharm: connot find declaration to go to
- ArcGIS TIN地表面与栅格地表面的生成与互相转换
- 【ArcGIS|空间分析|网络分析】3 使用网络数据集查找最佳路径
- Python 3 实现冒泡排序
- java怎样定义和使用数组,Java一维数组的定义和使用
- php数据库密码查询,php数据库查询及密码匹配的功能