Node.js数据流Stream之Readable流和Writable流

简介:

一、前传

Stream在很多语言都会有,当然Node.js也不例外。数据流是可读、可写、或即可读又可写的内存结构。Node.js中主要包括Readable、Writable、Duplex(双工)和Transform(变换)流。但是在学这些之前先学会util模块中的一个从其他对象继承的功能.

util模块提供了util.inherits()方法来允许你创建一个继承另一个对象的prototype(原形)方法的对象。当创建一个新对象时,prototype方法自动被使用。

util.inherits(constructor,superconstructor)原形constructor被设定为原形superConstructor,并在一个新的对象被创建时执行。可以通过使用constructor.super_属性从自定义对象的构造函数访问supercontructor.

二、Readable流

有的前传util模块从其他对象继承的功能的了解,Readable就很好理解了.主要它包含以下方法和事件。

1.事件:

readable:在数据块可以从流中读取的时候发出。

data:类似readable,不同之处在于,当数据的事件处理程序被连接时,流被转变成流动的模式,并且数据处理程序被连续的调用,直到所有数据都被用尽

end:当数据不再被提供时由流发出

close:当底层资源,如文件,已关闭时发出。

error:在接收数据中出错是发出。

2.方法:

read([size]):从流中读数据.数据可以是String、Buffer、null(下面代码会有),当指定size,那么只读仅限于那个字节数

setEncoding(encoding):设置read()请求读取返回String时使用的编码

pause():暂停从该对象发出的data事件

resume():恢复从该对象发出的data事件

pipe(destination,[options]):把这个流的输出传输到一个由deatination(目的地)指定的Writable流对象。options是一个js对象.例如:{end:true}当Readable结束时就结束Writable目的地。

unpipe([destination]):从Writale目的地断开这一对象。

3.demo:


var stream = require('stream');
var util = require('util');
util.inherits(Answers, stream.Readable);
function Answers(opt) {
  stream.Readable.call(this, opt);
  this.quotes = ["yes", "no", "maybe"];
  this._index = 0;
}
Answers.prototype._read = function() {
  if (this._index > this.quotes.length){
    this.push(null);
  } else {
    this.push(this.quotes[this._index]);
    this._index += 1;
  }
};
var r = new Answers();
console.log("Direct read: " + r.read().toString());
r.on('data', function(data){
  console.log("Callback read: " + data.toString());
});
r.on('end', function(data){
  console.log("No more answers.");
});
r.on('readable',function(data)
{
   console.log('readable');
});

"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe stream_read.js
Direct read: yes
readable
Callback read: no
Callback read: maybe
readable
readable
readable
No more answers.

Process finished with exit code 0


上面定义了一个通过util.inherits()继承Readable流的对象,从输出结果可以看到输出了3个字符串,但readable事件确执行了4次,其实前面也有写,read()可以是null,最后是push(null)了。

三、Writable流

有读就会有写,毕竟是可逆的,它和readable一样也有一些事件和方法

1.方法

write(chunk,[encoding],[callback]):将数据写入流。chunk(数据块)中包含要写入的数据,encoding指定字符串的编码,callback指定当数据已经完全刷新时执行的一个回调函数。如果成功写入,write()返回true.

end([chunk],[encoding],[callback]):与write()相同,它把Writable对象设为不再接受数据的状态,并发送finish事件。

2.事件

drain:在write()调用返回false后,当准备好开始写更多数据时,发出此事件通知监视器。

finish:当end()在Writable对象上调用,所以数据被刷新,并不会有更多的数据被接受时触发

pipe:当pipe()方法在Readable流上调用,已添加此writable为目的地时发出

unpipe:当unpipe()方法被调用,以删除Writable为目的地时发出。

3.demo


var stream = require('stream');
var util = require('util');
util.inherits(Writer, stream.Writable);
function Writer(opt) {
  stream.Writable.call(this, opt);
  this.data = new Array();
}
Writer.prototype._write = function(data, encoding, callback) {
  this.data.push(data.toString('utf8'));
  console.log("Adding: " + data);
  callback();
};
var w = new Writer();
for (var i=1; i<=5; i++){  
  w.write("Item" + i, 'utf8');
}
w.end("ItemLast");
console.log(w.data);

"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe stream_write.js
Adding: Item1
Adding: Item2
Adding: Item3
Adding: Item4
Adding: Item5
Adding: ItemLast
[ 'Item1', 'Item2', 'Item3', 'Item4', 'Item5', 'ItemLast' ]

Process finished with exit code 0

四、把Readable流用管道输送到Writable流

上面也介绍了Readable流pipe()方法,这个主要是来测试


var stream = require('stream');
var util = require('util');
util.inherits(Reader, stream.Readable);
util.inherits(Writer, stream.Writable);
function Reader(opt) {
  stream.Readable.call(this, opt);
  this._index = 1;
}
Reader.prototype._read = function(size) {
  var i = this._index++;
  if (i > 10){
    this.push(null);
  } else {
    this.push("Item " + i.toString());
  }
};
function Writer(opt) {
  stream.Writable.call(this, opt);
  this._index = 1;
}
Writer.prototype._write = function(data, encoding, callback) {
  console.log(data.toString());
  callback();
};

var r = new Reader();
var w = new Writer();
w.on('pipe',function(){
  console.log('pipe');
});
r.pipe(w);

"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe stream_piped.js
pipe
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10

Process finished with exit code 0
相关文章
|
存储 JavaScript 前端开发
js数据流详细讲解
【6月更文挑战第3天】这篇内容介绍了JavaScript中的数据流概念,包括单向和双向数据流模式。单向数据流是从父组件到子组件的单向传递,不直接修改数据;双向数据流允许父组件和子组件间数据同步更新。此外,文中还提到了状态管理(如Redux)、异步数据流处理、数据转换和实时数据流(WebSocket)等扩展话题,这些都是理解和优化JavaScript应用数据流的关键。
185 1
|
8月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
JavaScript
Node.js Stream(流)
10月更文挑战第4天
136 1
Node.js Stream(流)
|
消息中间件 JavaScript 前端开发
用于全栈数据流的 JavaScript、Node.js 和 Apache Kafka
用于全栈数据流的 JavaScript、Node.js 和 Apache Kafka
193 1
|
JavaScript
Node.js 流 Stream【详解】
Node.js 流 Stream【详解】
113 4
|
消息中间件 存储 JavaScript
构建一个基于Node.js的实时数据流处理系统
【5月更文挑战第30天】使用Node.js构建实时数据流处理系统,结合WebSocket实现双向通信,Kafka作为消息队列,Redis做数据存储和缓存,D3.js用于数据可视化。系统包括数据源、传输、处理、存储和可视化五个关键部分,适合高并发、低延迟的实时监控与分析需求。
|
JavaScript
Node.js Stream(流)
Node.js Stream(流)
70 0
|
4月前
|
JavaScript Unix Linux
nvm与node.js的安装指南
通过以上步骤,你可以在各种操作系统上成功安装NVM和Node.js,从而在不同的项目中灵活切换Node.js版本。这种灵活性对于管理不同项目的环境依赖而言是非常重要的。
1060 11
|
9月前
|
弹性计算 JavaScript 前端开发
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
Node.js 是一种高效的 JavaScript 运行环境,基于 Chrome V8 引擎,支持在服务器端运行 JavaScript 代码。本文介绍如何在阿里云上一键部署 Node.js 环境,无需繁琐配置,轻松上手。前提条件包括 ECS 实例运行中且操作系统为 CentOS、Ubuntu 等。功能特点为一键安装和稳定性好,支持常用 LTS 版本。安装步骤简单:登录阿里云控制台,选择扩展程序管理页面,安装 Node.js 扩展,选择实例和版本,等待创建完成并验证安装成功。通过阿里云的公共扩展,初学者和经验丰富的开发者都能快速进入开发状态,开启高效开发之旅。
|
8月前
|
资源调度 JavaScript 前端开发
前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
7357 23