理解nodejs的stream和pipe机制的原理和实现


Posted in NodeJs onAugust 12, 2017

前言

前几天别人请教我关于pipe的问题,我发现我虽然用了nodejs很久,但是由于每次用的不多所以经常回避stream的使用,导致一直不熟,现在重新学习整理一下相关知识。

通过nodeschool学习stream

nodeschool有一个stream-adventure教程教导stream的使用,很简单

简单stream进行pipe

首先,我们可以通过管道将输入定位到输出,输入输出可以是控制台或者文件流或者http请求,比如

process.stdin.pipe(process.stdout)
process.stdin.pipe(fs.createWriteStream(path))
fs.createReadStream(path).pipe(process.stdin)

pipe中间进行处理

如果我们想要在管道中间进行处理,比如想将输入的字符串变成大写写到输出里,我们可以使用一些可以作为中间处理的框架,比如through2就很方便

var through2 = require('through2');
var stream = through2(write,end)
process.stdin
  .pipe(stream)
  .pipe(process.stdout);

function write(line,_,next){
  this.push(line.toString().toUpperCase())
  next();
})
function end(done){
  done();
})

stream转化成普通回调

当我们输入是流,而输出是个普通函数,我们需要把输入流转化为普通的buffer,这时可以试用concat-stream库

var concat = require('concat-stream');

var reverseStream=concat(function(text){
  console.log(text.toString().split("").reverse().join(""));
})

process.stdin.pipe(reverseStream)

http server中的流

类似stdin和fs,http由于其特性也适合使用流,所以其自带类似特性

var http = require('http');
var server = http.createServer(function(req,res){
  req.pipe(res);
})

既作为输入也作为输出的流

request框架实现了如下功能,将一个流pipe到request请求中,然后将流的内容发给服务器,然后返回作为流供其他代码使用,实现如下

var request = require('request');
var r = request.post('http://localhost:8099');
process.stdin.pipe(r).pipe(process.stdout)

分支管道

下边是一个例子,这个例子将输入管道中html包含loud class的元素放入另一个管道进行大写操作,然后最后合并成输出

var trumpet = require('trumpet');
var through2 = require('through2');
var fs = require('fs');
var tr = trumpet();
var stream = tr.select('.loud').createStream();
var upper = through2(function(buf,_,next){
  this.push(buf.toString().toUpperCase());
  next();
})
stream.pipe(upper).pipe(stream);
process.stdin.pipe(tr).pipe(process.stdout);

合并输入输出stream例子

合并后的输入输出可像前文request一样使用,下边这个例子实现了使用流的方式进行子进程调用

var spawn = require('child_process').spawn;
var duplexer2 = require('duplexer2');

module.exports = function(cmd, args){
  var c = spawn(cmd,args)
  return duplexer2(c.stdin,c.stdout)
}

总结

通过上边的例子,可以知道stream应该还有如何合并等更复杂的应用方式。总之整体上符合如下特性:

  • Stream分为readable、writeble
  • Stream通过pipe方法控制流向
  • httpServer和httpClient和file system和process.stdin\out\err通常可以作为stream
  • Stream可以被on(event)转化为普通的变量,普通变量可以被write转换成stream
  • Stream自身可以被拆分、合并、过滤

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
Nodejs学习笔记之Global Objects全局对象
Jan 13 NodeJs
进阶之初探nodeJS
Jan 24 NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 NodeJs
nodejs创建简易web服务器与文件读写的实例
Sep 07 NodeJs
详解IWinter 一个路由转控制器的 Nodejs 库
Nov 15 NodeJs
nodejs实现截取上传视频中一帧作为预览图片
Dec 10 NodeJs
nodejs简单实现TCP服务器端和客户端的聊天功能示例
Jan 04 NodeJs
nodejs实现套接字服务功能详解
Jun 21 NodeJs
Nodejs把接收图片base64格式保存为文件存储到服务器上
Sep 26 NodeJs
NodeJS有难度的面试题(能答对几个)
Oct 09 NodeJs
Sublime Text3 配置 NodeJs 环境的方法
May 20 NodeJs
Windows下快速搭建NodeJS本地服务器的步骤
Aug 09 #NodeJs
让nodeJS支持ES6的词法----babel的安装和使用方法
Jul 31 #NodeJs
浅谈nodejs中的类定义和继承的套路
Jul 26 #NodeJs
nodejs之get/post请求的几种方式小结
Jul 26 #NodeJs
nodejs前端自动化构建环境的搭建
Jul 26 #NodeJs
nodejs body-parser 解析post数据实例
Jul 26 #NodeJs
深入解析nodejs HTTP服务
Jul 25 #NodeJs
You might like
无线电广播与收音机发展的历史回眸
2021/03/02 无线电
Apache2 httpd.conf 中文版
2006/11/17 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
php操作mongoDB实例分析
2014/12/29 PHP
Thinkphp框架开发移动端接口(1)
2016/08/18 PHP
PHP操作XML中XPath的应用示例
2019/07/04 PHP
js读取注册表的键值示例
2013/09/25 Javascript
在javascript中实现函数数组的方法
2013/12/25 Javascript
Js使用WScript.Shell对象执行.bat文件和cmd命令
2014/12/18 Javascript
jQuery简单几行代码实现tab切换
2015/03/10 Javascript
自定义百度分享的分享按钮
2015/03/18 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
2015/05/09 Javascript
jQuery实现大转盘抽奖活动仿QQ音乐代码分享
2015/08/21 Javascript
微信小程序 animation API详解及实例代码
2016/10/08 Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
2016/10/11 Javascript
JavaScript利用闭包实现模块化
2017/01/13 Javascript
jquery实现提示语淡入效果
2017/05/05 jQuery
JS实现横向轮播图(中级版)
2020/01/18 Javascript
Electron+vue从零开始打造一个本地播放器的方法示例
2020/10/27 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
2020/10/28 Javascript
js前端对于大量数据的展示方式及处理方法
2020/12/02 Javascript
PHP魔术方法__ISSET、__UNSET使用实例
2014/11/25 Python
在Python中通过threading模块定义和调用线程的方法
2016/07/12 Python
Python通过Pygame绘制移动的矩形实例代码
2018/01/03 Python
Python3实现的判断回文链表算法示例
2019/03/08 Python
关于python3中setup.py小概念解析
2019/08/22 Python
解决pytorch 交叉熵损失输出为负数的问题
2020/07/07 Python
matplotlib 三维图表绘制方法简介
2020/09/20 Python
女性时尚网购:Chic Me
2019/07/30 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
捐书寄语赠言
2014/01/18 职场文书
分层教学实施方案
2014/03/19 职场文书
省级优秀班集体申报材料
2014/05/25 职场文书
银行求职信范文
2014/05/26 职场文书
Windows安装Anaconda3的方法及使用过程详解
2021/06/11 Python
zabbix如何添加监控主机和自定义监控项
2022/08/14 Servers