源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Node.js中的流(Stream)介绍

  • 时间:2020-12-12 12:31 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Node.js中的流(Stream)介绍
[b]什么是流?[/b] 说到流,就涉及到一个*nix的概念:[url=http://zh.wikipedia.org/wiki/%E7%AE%A1%E9%81%93_(Unix)]管道[/url]——在*nix中,流在Shell中被实现为可以通过 |(管道符) 进行桥接的数据,一个进程的输出(stdout)可被直接作为下一个进程的输入(stdin)。 在Node中,流([url=https://nodejs.org/api/stream.html]Stream[/url])的概念与之类似,代表一种数据流可供桥接的能力。 [b]pipe[/b] 流化的精髓在于 .pipe()方法。可供桥接的能力,在于数据流的两端(上游/下游 或称为 读/写流)以一个 .pipe()方法进行桥接。 [img]http://files.jb51.net/file_images/article/201503/2015330112505188.jpg?2015230112514[/img] 伪代码的表现形式为:
[url=https://nodejs.org/api/stream.html#stream_class_stream_readable_1]stream.Readable[/url]    可读流(需要实现_read方法,关注点在于对数据流读取的细节 2.[url=https://nodejs.org/api/stream.html#stream_class_stream_writable_1]stream.Writable [/url]    可写流(需要实现_write方法,关注点在于对数据流写入的细节 3.[url=https://nodejs.org/api/stream.html#stream_class_stream_duplex_1]stream.Duplex[/url]        可读/写流(需要实现以上两接口,关注点为以上两接口的细节 4.[url=https://nodejs.org/api/stream.html#stream_class_stream_transform_1]stream.Transform  [/url]继承自Duplex(需要实现_transform方法,关注点在于对数据块的处理 简单来说: 1).pipe() 的拥有者一定具备 Readable 流(并不局限于)能力,它拥有 'readable'/'data'/'end'/'close'/'error' 一系列事件可供订阅,也提供 .read()/.pause()/.resume()等一系列方法供调用; 2).pipe() 的参数一定具备Writable 流(并不局限于 )能力,它拥有 'drain'/'pipe'/'unpipe'/'error'/'finish' 事件可供访问,也提供 .write()/.end() 等一系列方法供调用 [b]什么鬼[/b] 有没有一丝丝焦虑?别急,做为一个说人话的低级码工,我会把Stream掰开了和您扯一扯的。 Stream类,在 [url=https://github.com/joyent/node/blob/master/lib/stream.js]Node.js的源码[/url] 里,是这么定义的:
[url=https://nodejs.org/api/http.html#http_event_connect_1]经典socket示例[/url] 中那样:
[u]复制代码[/u] 代码如下:
req.on('connect', function(res, socket, head) {     socket.on('data', function(chunk) {       console.log(chunk.toString());     });     socket.on('end', function() {       proxy.close();     });   });
[b]Readable流状态的切换 [/b]需要注意的是,Readable 流有两种状态:flowing mode(激流) 和 pause  mode(暂停)。前者根本停不下来,谁被pipe上了就马上不停的给;后者会暂停,直到下游显式的调用 Stream.read() 请求才读取数据块。Readable 流初始化时是 pause mode的。 这两种状态可以互为切换的,其中, 有以下任一行为,pause 转 flowing: 1.对 Readable 流添加一个data事件订阅 2.对 Readable 调用 .resume() 显式开启flowing 3.调用 Readable 流的 .pipe(writable) ,桥接到一个 Writable 流上 有以下任一行为,flowing 转回 pause: 1.Readable 流还没有 pipe 到任何流上,可调 .pause() 暂停 2.Readable 流已经 pipe 到了流上,需 remove 掉所有 data 事件订阅,并且调用 .unpipe()方法逐一解除与下游流的关系 [b]妙用[/b] 结合流的异步特性,我可以写出这样的应用:直接将 用户A 的输出桥接到 用户B 的页面上输出:
[u]复制代码[/u] 代码如下:
router.post('/post', function(req, res) {     var destination = req.headers['destination']; //发给谁     cache[destionation] = req;     //是的,并不返回,所以最好是个ajax请求 });
用户B请求的时候:
[u]复制代码[/u] 代码如下:
router.get('/inbox', function(req, res){     var user = req.headers['user'];     cache.find(user, function(err, previousReq){ //找到之前存的req        var form = new multiparty.Form();        form.parse(previousReq);  // 有文件给我        form.on('part', function (part) {             part.pipe(res); //流式大法好:)               part.on('error', function (err) {                 console.log(err);                 messaging.setRequestDone(uniqueID);                 return res.end(err);             });         });     }); });
[b]参考[/b] how to write node programs with streams: stream-handbook
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部