理解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的HTML分析利器node-jquery用法浅析
Nov 08 NodeJs
用nodejs搭建websocket服务器
Jan 23 NodeJs
NodeJS配置HTTPS服务实例分享
Feb 19 NodeJs
详解使用nodeJs安装Vue-cli
May 17 NodeJs
nodejs socket实现的服务端和客户端功能示例
Jun 02 NodeJs
详解使用vscode+es6写nodejs服务端调试配置
Sep 21 NodeJs
使用nodejs+express实现简单的文件上传功能
Dec 27 NodeJs
NodeJS 中Stream 的基本使用
Jul 30 NodeJs
NVM安装nodejs的方法实用步骤
Jan 16 NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 NodeJs
搭建一个nodejs脚手架的方法步骤
Jun 28 NodeJs
浅谈JS和Nodejs中的事件驱动
May 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
sqlyog 中文乱码问题的设置方法
2008/10/19 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
用 Javascript 验证表单(form)中多选框(checkbox)值
2009/09/08 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
2012/10/11 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
2014/07/17 Javascript
js实现网页右上角滑出会自动消失大幅广告的方法
2015/02/27 Javascript
jquery ztree实现模糊搜索功能
2016/02/25 Javascript
node.js学习之交互式解释器REPL详解
2016/12/08 Javascript
纯JS实现表单验证实例
2016/12/24 Javascript
jQuery+ajax实现局部刷新的两种方法
2017/06/08 jQuery
ES6新特性:使用export和import实现模块化详解
2017/07/31 Javascript
js链表操作(实例讲解)
2017/08/29 Javascript
jquery插件开发模式实例详解
2019/07/20 jQuery
es6 super关键字的理解与应用实例分析
2020/02/15 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
python单线程实现多个定时器示例
2014/03/30 Python
学习python 之编写简单乘法运算题
2016/02/27 Python
基于Python 装饰器装饰类中的方法实例
2018/04/21 Python
Python之列表的插入&替换修改方法
2018/06/28 Python
django 自定义filter 判断if var in list的例子
2019/08/20 Python
Python高级特性 切片 迭代解析
2019/08/23 Python
导致python中import错误的原因是什么
2020/07/01 Python
python 浮点数四舍五入需要注意的地方
2020/08/18 Python
python+opencv实现车道线检测
2021/02/19 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
eBay比利时购物网站:eBay.be
2019/08/09 全球购物
Geekbuying波兰:购买中国电子产品
2019/10/20 全球购物
俄罗斯最大的隐形眼镜销售网站:Ochkov.Net
2021/02/07 全球购物
法学专业本科生自荐信范文
2013/12/17 职场文书
建筑工地标语
2014/06/18 职场文书
2014年自愿离婚协议书范本
2014/09/25 职场文书
太空授课观后感
2015/06/17 职场文书
《狮子和鹿》教学反思
2016/02/16 职场文书
一次线上mongo慢查询问题排查处理记录
2022/03/18 MongoDB
MySQL数据库配置信息查看与修改方法详解
2022/06/25 MySQL