理解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学习笔记之Http模块
Jan 13 NodeJs
Nodejs实现批量下载妹纸图
May 28 NodeJs
iPhone手机上搭建nodejs服务器步骤方法
Jul 06 NodeJs
nodejs初步体验篇
Nov 23 NodeJs
nodejs的压缩文件模块archiver用法示例
Jan 18 NodeJs
Nodejs基于LRU算法实现的缓存处理操作示例
Mar 17 NodeJs
NodeJs测试框架Mocha的安装与使用
Mar 28 NodeJs
详解nodejs实现本地上传图片并预览功能(express4.0+)
Jun 28 NodeJs
使用nodeJs来安装less及编译less文件为css文件的方法
Nov 20 NodeJs
nodejs搭建本地服务器轻松解决跨域问题
Mar 21 NodeJs
深入理解NodeJS 多进程和集群
Oct 17 NodeJs
NodeJS http模块用法示例【创建web服务器/客户端】
Nov 05 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
JpGraph php柱状图使用介绍
2011/08/23 PHP
PHP 解决session死锁的方法
2013/06/20 PHP
php获取文件大小的方法
2014/02/26 PHP
PHP编程实现csv文件导入mysql数据库的方法
2017/04/29 PHP
js一组验证函数
2008/12/20 Javascript
Jquery 绑定时间实现代码
2011/05/03 Javascript
Javascript的常规数组和关联数组对比小结
2012/05/24 Javascript
js对图片base64编码字符串进行解码并输出图像示例
2014/03/17 Javascript
jquery自动将form表单封装成json的具体实现
2014/03/17 Javascript
Jquery 获取指定标签的对象及属性的设置与移除
2014/05/29 Javascript
jQuery回调函数的定义及用法实例
2014/12/23 Javascript
JS+CSS实现大气的黑色首页导航菜单效果代码
2015/09/10 Javascript
js创建jsonArray传输至后台及后台全面解析
2016/04/11 Javascript
javascript js 操作数组 增删改查的简单实现
2016/06/20 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
2017/01/19 Javascript
js实现图片360度旋转
2017/01/22 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
详解react关于事件绑定this的四种方式
2018/03/09 Javascript
JS实现的缓冲运动效果示例
2018/04/30 Javascript
JS实现字符串中去除指定子字符串方法分析
2018/05/17 Javascript
vue实现条件叠加搜索的解决方法
2019/05/28 Javascript
[01:54]胎教DOTA2 准妈妈玩家现身中国区预选赛
2016/06/26 DOTA
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
Python实现从url中提取域名的几种方法
2014/09/26 Python
Python __setattr__、 __getattr__、 __delattr__、__call__用法示例
2015/03/06 Python
Python利用Beautiful Soup模块搜索内容详解
2017/03/29 Python
Python画图高斯分布的示例
2019/07/10 Python
为什么python比较流行
2020/06/19 Python
Python tkinter制作单机五子棋游戏
2020/09/14 Python
HTML5实现获取地理位置信息并定位功能
2015/04/25 HTML / CSS
Spartoo美国:欧洲排名第一的在线时装零售商
2019/12/12 全球购物
人事文员岗位职责
2014/02/16 职场文书
六年级学生评语
2014/04/22 职场文书
篮球赛口号
2014/06/18 职场文书
2014年惩防体系建设工作总结
2014/12/01 职场文书
学习社交礼仪心得体会
2016/01/22 职场文书