理解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开发cli项目实例
Jun 03 NodeJs
nodejs获取微信小程序带参数二维码实现代码
Apr 12 NodeJs
详解nodejs express下使用redis管理session
Apr 24 NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 NodeJs
nodejs实现截取上传视频中一帧作为预览图片
Dec 10 NodeJs
nodejs读取并去重excel文件
Apr 22 NodeJs
nodejs用gulp管理前端文件方法
Jun 24 NodeJs
nodejs初始化init的示例代码
Oct 10 NodeJs
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
Mar 02 NodeJs
nodejs对项目下所有空文件夹创建gitkeep的方法
Aug 02 NodeJs
Nodejs实现微信分账的示例代码
Jan 19 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 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
php使用strtotime和date函数判断日期是否有效代码分享
2013/12/25 PHP
php二维数组转成字符串示例
2014/02/17 PHP
PHP中时间加减函数strtotime用法分析
2017/04/26 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
PHP实现基于3DES算法加密解密字符串示例
2018/08/24 PHP
xtree.js 代码
2007/03/13 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
Jquery选择器中使用变量实现动态选择例子
2014/07/25 Javascript
cocos2dx骨骼动画Armature源码剖析(一)
2015/09/08 Javascript
jQuery滚动加载图片实现原理
2015/12/14 Javascript
基于JavaScript实现图片剪切效果
2017/03/07 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
BootStrap 导航条实例代码
2017/05/18 Javascript
利用vue.js把静态json绑定bootstrap的table方法
2018/08/28 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
JS常用正则表达式超全集(密码强度校验,金额校验,IE版本,IPv4,IPv6校验)
2020/02/03 Javascript
JavaScript实现消消乐的源代码
2021/01/12 Javascript
跟老齐学Python之再深点,更懂list
2014/09/20 Python
Python脚本实现网卡流量监控
2015/02/14 Python
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
Python解惑之整数比较详解
2017/04/24 Python
pyqt5 QProgressBar清空进度条的实例
2019/06/21 Python
Python字符串split及rsplit方法原理详解
2020/06/29 Python
用python读取xlsx文件
2020/12/17 Python
澳大利亚家庭花园和DIY工具网店:VidaXL
2019/05/03 全球购物
岗位职责的含义
2013/11/17 职场文书
2014年大学生四年规划书范文
2014/04/03 职场文书
经济类毕业生求职信
2014/06/26 职场文书
检察院院长群众路线教育实践活动个人整改措施
2014/10/04 职场文书
见义勇为事迹材料
2014/12/24 职场文书
写给老师的感谢信
2015/01/20 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
教师读书笔记
2015/06/29 职场文书
小学三年级数学教学反思
2016/02/16 职场文书
SQLServer2008提示评估期已过解决方案
2021/04/12 SQL Server
使用Java去实现超市会员管理系统
2022/03/18 Java/Android