流在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的诞生相关推荐

  1. stream pipe的原理及简化源码分析

    前言 在编写代码时,我们应该有一些方法将程序像连接水管一样连接起来 -- 当我们需要获取一些数据时,可以去通过"拧"其他的部分来达到目的.这也应该是IO应有的方式. -- Doug ...

  2. NODE Stream流总结(1)

    Stream简介 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). Stream模块提供了基础的API, 使用这些API可以很容易地来构建实现流 ...

  3. Node 深入Stream(2)

    1. Node.js 中有四种基本的流类型: Readable - 可读的流 (例如 fs.createReadStream()). Writable - 可写的流 (例如 fs.createWrit ...

  4. Node.js Stream(流) 简单易懂全解析

    一.node.js中的流是什么 stream(流)是Node.js提供的又一个仅在服务区端可用的模块,流是一种抽象的数据结构.Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如, ...

  5. node随笔-数据流Stream

    一. 流(stream) 在 Node.js 中是处理流数据的抽象接口(abstract interface), stream 模块提供了基础的 API .使用这些 API 可以很容易地来构建实现流接 ...

  6. Node.js: 认识流stream

    流是Node.js中一个非常重要的概念, 也是Node.js之所以适用于I/O密集型场景的重要原因之一. 流是Node.js移动数据的方式,流可以是可读的和/或可写的.在Node.js中很多模块都使用 ...

  7. 接收大文件流_一文搞定 Node.js 流 (Stream)

    stream(流)是一种抽象的数据结构.就像数组或字符串一样,流是数据的集合. 不同的是,流可以每次输出少量数据,而且它不用存在内存中. 比如,对服务器发起 http 请求的 request/resp ...

  8. Node.js之Stream

    Node.js之Stream 例子1 Steam-流 例子2\3 管道 Stream对象的原型链 Stream的分类 自创流 例子1 const fs = require("fs" ...

  9. node.js使用手册_权威的Node.js手册

    node.js使用手册 Note: you can get a PDF, ePub, or Mobi version of this handbook for easier reference, or ...

  10. base64 转二进制_一篇文章弄明白Node.js与二进制数据流

    1 认识二进制数据 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二", ...

最新文章

  1. Intel SGX Remote Attestation实例代码安装和执行,笔记
  2. Google Chrome 增加拦截恶意下载的支持
  3. HashSet源码分析 jdk1.6
  4. 《多元统计分析》学习笔记之主成分分析
  5. 在使用ToolBar + AppBarLayout,实现上划隐藏Toolbar功能,遇到了一个坑。
  6. Java基础——类加载机制
  7. 倒N字形排列java_Java排序8大算法实现
  8. 如何查看电脑是几核几线程
  9. vsync信号产生与分发
  10. SQL中GROUP BY的理解
  11. 设计模式--适配器(Adapter)
  12. Struts2 文件上传 文件类型 大小过滤
  13. 虫师Selenium2+Python_11、自动化测试项目实战
  14. javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
  15. python将图片转为矢量图
  16. java学习(方法)
  17. 前端框架 ng 环境配置
  18. PHP 阿里云实人认证
  19. 在配有通道的计算机系统中,用户程序需要输出时,引起的中断是,计算机系统结构自考2009年7月真题...
  20. K8S 快速入门(十六)实战篇:StorageClass(存储类)

热门文章

  1. 传统高斯模糊与优化算法(附完整C++代码)
  2. 图像去雾:基于暗通道的去雾算法 - 附代码
  3. 【pytorch】RuntimeError: 1only batches of spatial targets supported (3D tensors) but got targets of si
  4. 从零基础入门Tensorflow2.0 ----八、43. 自定义流程分布式
  5. pycharm: connot find declaration to go to
  6. ArcGIS TIN地表面与栅格地表面的生成与互相转换
  7. 【ArcGIS|空间分析|网络分析】3 使用网络数据集查找最佳路径
  8. Python 3 实现冒泡排序
  9. java怎样定义和使用数组,Java一维数组的定义和使用
  10. php数据库密码查询,php数据库查询及密码匹配的功能