理解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获取本机内网和外网ip地址的实现代码
Jun 01 NodeJs
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
nodejs初步体验篇
Nov 23 NodeJs
快速掌握Node.js之Window下配置NodeJs环境
Mar 21 NodeJs
NodeJS 实现手机短信验证模块阿里大于功能
Jun 19 NodeJs
nodejs调取微信收货地址的方法
Dec 20 NodeJs
NodeJS实现不可逆加密与密码密文保存的方法
Mar 16 NodeJs
nodejs express配置自签名https服务器的方法
May 22 NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 NodeJs
深入理解NodeJS 多进程和集群
Oct 17 NodeJs
关于NodeJS中的循环引用详解
Jul 23 NodeJs
nodejs语言实现验证码生成功能的示例代码
Oct 13 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 将bmp图片转为jpg等其他任意格式的图片
2009/06/29 PHP
基于php下载文件的详解
2013/06/02 PHP
PHP之sprintf函数用法详解
2014/11/12 PHP
PHP ADODB实现分页功能简单示例
2018/05/25 PHP
Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
2019/04/02 PHP
Laravel基础-关于引入公共文件的两种方式
2019/10/18 PHP
20个非常有用的PHP类库 加速php开发
2010/01/15 Javascript
juqery 学习之五 文档处理 插入
2011/02/11 Javascript
Jquery判断form表单数据是否变化
2016/03/30 Javascript
JavaScript面试开发常用的知识点总结
2016/08/08 Javascript
jQuery css() 方法动态修改CSS属性
2016/09/25 Javascript
bootstrap常用组件之头部导航实现代码
2017/04/20 Javascript
Require.JS中的几种define定义方式示例
2017/06/01 Javascript
js实现各浏览器全屏代码实例
2018/07/03 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
2018/09/26 Javascript
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
2019/05/08 Javascript
vue多页面项目中路由使用history模式的方法
2019/09/23 Javascript
五句话帮你轻松搞定js原型链
2020/12/09 Javascript
[59:00]OG vs TNC 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[47:10]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第二场 12.16
2020/12/18 DOTA
Python实现按特定格式对文件进行读写的方法示例
2017/11/30 Python
matplotlib中legend位置调整解析
2017/12/19 Python
python爬取指定微信公众号文章
2018/12/20 Python
详解从Django Rest Framework响应中删除空字段
2019/01/11 Python
python查询文件夹下excel的sheet名代码实例
2019/04/02 Python
Django中使用 Closure Table 储存无限分级数据
2019/06/06 Python
Python实现某论坛自动签到功能
2019/08/20 Python
python利用opencv保存、播放视频
2020/11/02 Python
关于老式浏览器兼容HTML5和CSS3的问题
2016/06/01 HTML / CSS
Under Armour安德玛法国官网:美国高端运动科技品牌
2018/06/29 全球购物
英国领先品牌手动工具和电动工具供应商:Tooled Up
2018/11/24 全球购物
Guess欧洲官网:美国服饰品牌
2019/08/06 全球购物
授权委托书
2014/09/17 职场文书
2015年度学校卫生工作总结
2015/05/12 职场文书
大学生入党自我鉴定范文
2019/06/21 职场文书
接触艺术对孩子学习思维有益
2019/08/06 职场文书