理解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和PhantomJS抓取网站页面信息以及网站截图
Nov 18 NodeJs
使用Nodejs开发微信公众号后台服务实例
Sep 03 NodeJs
nodejs中使用多线程编程的方法实例
Mar 24 NodeJs
Nodejs实现批量下载妹纸图
May 28 NodeJs
详解nodejs中exports和module.exports的区别
Feb 17 NodeJs
Nodejs多站点切换Htpps协议详解及简单实例
Feb 23 NodeJs
nodejs中模块定义实例详解
Mar 18 NodeJs
nodejs入门教程五:连接数据库的方法分析
Apr 24 NodeJs
关于Mac下安装nodejs、npm和cnpm的教程
Apr 11 NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 NodeJs
监控Nodejs的性能实例代码
Jul 02 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
附件名前加网站名
2008/03/23 PHP
坏狼php学习 计数器实例代码
2008/06/15 PHP
php URL编码解码函数代码
2009/03/10 PHP
建站常用13种PHP开源CMS比较
2009/08/23 PHP
PHP语言中global和$GLOBALS[]的分析 之二
2012/02/02 PHP
分享PHP函数实现数字与文字分页代码
2015/07/28 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
基于JQuery的密码强度验证代码
2010/03/01 Javascript
如何用JavaScript定义一个类
2014/09/12 Javascript
JavaScript实现身份证验证代码
2016/02/17 Javascript
js匿名函数作为函数参数详解
2016/06/01 Javascript
AngularJS监听路由的变化示例代码
2016/09/23 Javascript
js获取浏览器和屏幕的各种宽度高度
2017/02/22 Javascript
node.js读取Excel数据(下载图片)的方法示例
2018/08/02 Javascript
vue里面使用mui的弹出日期选择插件实例
2018/09/16 Javascript
Vue-input框checkbox强制刷新问题
2019/04/18 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
2019/12/06 Javascript
element-ui点击查看大图的方法示例
2020/12/14 Javascript
使用jquery实现轮播图效果
2021/01/02 jQuery
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
[27:53]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS iG
2014/05/26 DOTA
[41:37]DOTA2北京网鱼队选拔赛——冲击职业之路
2015/04/13 DOTA
讲解Python中运算符使用时的优先级
2015/05/14 Python
利用Python中的pandas库对cdn日志进行分析详解
2017/03/07 Python
Ubuntu下使用python读取doc和docx文档的内容方法
2018/05/08 Python
基于python3 OpenCV3实现静态图片人脸识别
2018/05/25 Python
浅析PyTorch中nn.Linear的使用
2019/08/18 Python
Python环境搭建过程从安装到Hello World
2021/02/05 Python
CSS3实现缺角矩形,折角矩形以及缺角边框
2019/12/20 HTML / CSS
如何使用amaze ui的分页样式封装一个通用的JS分页控件
2020/08/21 HTML / CSS
德国汉莎航空中国官网: Lufthansa中国
2017/03/30 全球购物
服装设计师职业生涯规划范文
2014/02/28 职场文书
大学新生军训自我鉴定范文
2014/09/13 职场文书
先进党员事迹材料
2014/12/24 职场文书
英语邀请函范文
2015/02/02 职场文书
申论不会写怎么办?教您掌握这6点思维和原则
2019/07/17 职场文书