理解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 相关文章推荐
PHPStorm 2020.1 调试 Nodejs的多种方法详解
Sep 17 NodeJs
Nodejs Post请求报socket hang up错误的解决办法
Sep 25 NodeJs
nodejs事件的监听与触发的理解分析
Feb 12 NodeJs
nodejs实现HTTPS发起POST请求
Apr 23 NodeJs
实例详解Nodejs 保存 payload 发送过来的文件
Jan 14 NodeJs
详解NodeJS框架express的路径映射(路由)功能及控制
Mar 24 NodeJs
nodejs个人博客开发第六步 数据分页
Apr 12 NodeJs
nodejs操作mongodb的填删改查模块的制作及引入实例
Jan 02 NodeJs
详解Nodejs内存治理
May 13 NodeJs
NodeJs入门教程之定时器和队列
Mar 08 NodeJs
使用nodejs分离html文件里的js和css详解
Apr 12 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 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
支付宝服务窗API接口开发php版本
2016/07/20 PHP
php实现简单的守护进程创建、开启与关闭操作
2019/08/13 PHP
Firefox 无法获取cssRules 的解决办法
2006/10/11 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
struts2+jquery+json实现异步加载数据(自写)
2013/06/24 Javascript
javascript实现简单的鼠标拖动效果实例
2015/04/10 Javascript
使用控制台破解百小度一个月只准改一次名字
2015/08/13 Javascript
第三章之Bootstrap 表格与按钮功能
2016/04/25 Javascript
基于jquery实现三级下拉菜单
2016/05/10 Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
2016/10/10 Javascript
Javascript动画效果(1)
2016/10/11 Javascript
微信小程序 SocketIO 实例讲解
2016/10/13 Javascript
vue模板语法-插值详解
2017/03/06 Javascript
vue+axios实现登录拦截的实例代码
2017/05/22 Javascript
ES6解构赋值实例详解
2017/10/31 Javascript
小程序实现留言板
2018/11/02 Javascript
Python提取Linux内核源代码的目录结构实现方法
2016/06/24 Python
matplotlib subplots 设置总图的标题方法
2018/05/25 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
人工神经网络算法知识点总结
2019/06/11 Python
django框架事务处理小结【ORM 事务及raw sql,customize sql 事务处理】
2019/06/27 Python
淘宝秒杀python脚本 扫码登录版
2019/09/19 Python
python 正则表达式参数替换实例详解
2020/01/17 Python
python实现四人制扑克牌游戏
2020/04/22 Python
用Python开发app后端有优势吗
2020/06/29 Python
pandas统计重复值次数的方法实现
2021/02/20 Python
莫斯科高科技在线商店:KremlinStore
2019/03/13 全球购物
法国购买隐形眼镜和眼镜网站:Optical Center
2019/10/08 全球购物
bonprix荷兰网上商店:便宜的服装、鞋子和家居用品
2020/07/04 全球购物
办公室文书岗位职责
2013/12/16 职场文书
职业生涯规划书前言
2014/04/15 职场文书
2014年大学班长工作总结
2014/11/14 职场文书
毕业生学校组织意见
2015/06/04 职场文书
先进教师个人主要事迹材料
2015/11/03 职场文书
手把手教你导入Go语言第三方库
2021/08/04 Golang
centos8安装MongoDB的详细过程
2021/10/24 MongoDB