Node.js中的流介绍
什么是流量?
说到流,涉及到一个*nix的概念:管道——在*nix中,流在Shell中实现为可以用|(管道字符)桥接的数据,一个进程的输出(stdout)可以直接作为下一个进程的输入(stdin)。
在Node中,Stream的概念是相似的,它代表了数据流被桥接的能力。
管
流态化的本质在于。pipe()方法。桥接的能力是数据流的两端(上游/下游或读/写流)通过. pipe()方法桥接。
伪码表示如下:复制的代码如下://上游。管道(下游)可读。管道(可写);
流量分类
在Node v0.4之前,无意讨论所谓的“经典”流程.然后,流被分成几个类别(所有抽象接口:
1 . stream . read stream(需要实现_read方法,关注数据流读取的细节2 . stream . write stream(需要实现_write方法,关注数据流写入的细节3.stream.Duplex可读/可写stream(需要实现以上两个接口,关注以上两个接口的细节4.stream.Transform继承自Duplex(需要实现_transform)
简单地说:
1)的所有者。pipe()必须具有(但不限于)Readable stream的功能,该功能具有一系列事件,如订阅的“Readable”/“data”/“end”/“close”/“error”,还提供了一系列方法,如。read()/。pause()/。resume()用于呼叫;2)的参数。管道()必须具有可写流的能力(但不限于)。它具有用于访问的“drain”/“pipe”/“unpipe”/“error”/“finish”事件,并且还提供了一系列方法,例如。write()/。end()用于调用
究竟
有焦虑的痕迹吗?别担心,作为一个会说人话的低级程序员,我会打破流和你说话。
Node.js源代码中的Stream类定义如下:复制代码如下: var ee=require ('events ')。eventemittervar util=require(' util ');继承;函数Stream(){ ee . call(this);}
可以看出,本质上Stream是一个EventEmitter,也就是说它具有事件驱动功能(。发出/。在.).众所周知,“Node.js是基于V8的事件驱动平台”,实现了事件驱动的流编程,具有与Node相同的异步回调特性。
例如,在可读流中,有一个可读事件。在挂起的只读流中,只要数据块准备好被读取,它就会被发送给订户(什么是可读流?express中的req、ftp或mutli表单上传组件的req.part、标准输入过程、系统中的stdin等。).有了可读事件,我们就可以成为一个工具,比如处理shell命令输出的分析器:复制代码如下:process.stdin.on('可读',function(){ varbuf=process . stdin . read();if(buf){ var data=buf . tostring();//解析数据.}});
像这样调用:
复制代码如下: head-10some . txt | node parser . js。
对于Readable流,我们还可以订阅它的数据和end事件来获取数据块,并在流耗尽时获得通知,就像经典的socket示例一样:复制代码如下: req.on ('connect '),function (res,socket,head) {socket.on ('data '),function(chunk){ console . log(chunk。});socket.on('end ',function(){ proxy . close();});});
需要注意的是,可读流有两种状态:流动模式和暂停模式。前者根本停不下来,管上谁就马上给;后者将暂停,直到下游显式调用Stream.read()请求来读取数据块。初始化时,可读流处于暂停模式。
这两种状态可以相互切换,其中,
有以下任何行为,暂停到流动:
1.向可读流添加数据事件订阅。2.打电话。resume()到可读流以显式打开流3。3.打电话。可读流的管道(可写)和到可写流的桥
如果出现以下任何行为,流动会返回暂停状态:
1.易读的流还没有管到任何流上,可调。暂停()暂停2.易读的流已经管到了流上,需移动掉所有数据事件订阅,并且调用取消固定()方法逐一解除与下游流的关系
妙用
结合流的异步特性,我可以写出这样的应用:直接将用户A的输出桥接到用户B的页面上输出:复制代码代码如下:router.post('/post ',函数(req,RES){ var destination=req。标头['目标'];//发给谁缓存[设计]=请求;//是的,并不返回,所以最好是个创建交互式、快速动态网页应用的网页开发技术请求});
用户B请求的时候:
复制代码代码如下:router.get('/inbox ',函数(req,RES){ var user=req。标题['用户'];cache.find(用户,函数(err,previousReq){ //找到之前存的请求变化形式=新多方form();形式。解析(previousReq);//有文件给我form.on('part ',function(part){ part。管道(RES);//流式大法好:) part.on('error ',function(err){ console。日志(err);信息。setrequest done(uniqueID);返回RES . end(err);});});});});
参考
如何用溪流编写节点程序:流手册
版权声明:Node.js中的流介绍是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。