美文网首页
nodejs流编程入门

nodejs流编程入门

作者: kuulid | 来源:发表于2019-01-06 17:52 被阅读9次

nodejs中的流

流是什么,应该很好理解,计算机中数据流处处存在。linux的管道设计就是利用了流的概念,所有的数据处理就像流水一样通过管道一层层的处理。而nodejs中的stream模块就是流,它是 EventEmitter 的实例。

一个简单的http echo服务:

const http = require('http');

const server = http.createServer((req, res) => {
    // req 是一个 http.IncomingMessage 实例,它是可读流。
    // res 是一个 http.ServerResponse 实例,它是可写流。

    let body = '';
    req.setEncoding('utf8');

    //所有的流都是EventEmitter的实例,数据接收的事件
    req.on('data', (chunk) => {
        body += chunk;
    });

    req.on('end', () => {
        try {
            res.write(body);
            res.end();
        } catch(e) {
            // json 解析失败。
            res.statusCode = 400;
            return res.end(`错误: ${e.message}`);
        }
    })
});

server.listen(3000);

上面的例子,res和req就是标准的流,http.IncomingMessage实现了stream.Readable
接口,而http.ServerResponse则继承了stream

nodejs流的类型

Node.js 中有四种基本的流类型:

可读和可写流上面已经见过了,比较简单,基本就是一个读一个写,如fs.createWriteStream创建一个可写流,向文件写入数据:

const fs = require('fs');

const writeFileStream = fs.createWriteStream('./data.txt');

for (let i = 0; i < 1000; i ++ ) {
    writeFileStream.write(Math.random().toString());
}

可读流也很简单,read方法读取数据,还有一个pipe方法,接受一个<stream.Writable>
对象,可以绑定可写流到可读流,将可读流自动切换到流动模式,并将可读流的所有数据推送到绑定的可写流。 数据流会被自动管理,所以即使可读流更快,目标可写流也不会超负荷。
所有的流都是EventEmitter的实例,所以任何流会暴露关键事件可以监听。
运行完上面写入流的例子,在写一个读文件并放入管道进行压缩的demo:

const fs = require('fs');
const zlib = require('zlib');

fs.createReadStream('./data.txt')
    .pipe(zlib.createGzip())
    .pipe(fs.createWriteStream('input.txt.gz'));

流背后的简单原理

Flowing Mode

Flowing Mode

其实流就是生产者和消费者问题,在处理大数据流动和大文件的时候非常有用,生产者并不直接给消费者,而是而是先 push 到缓存池,缓存池有一个水位标记 highWatermark,超过这个标记阈值,push 的时候会返回 false。这种情况被称为“背压”,一般是生产者过快,如下;

const Chance = require('chance');
const chance = new Chance();


require('http').createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});

    function generateMore() {
        while(chance.bool( { likelihood: 95 } )) {
            let shouldContince = res.write(
                chance.string({ length: ( 16 * 1024) -1 })
            );

            if (!shouldContince) {
                console.log('Backpressure');
                return res.once('drain', generateMore);
            }
        }
        res.end('\nThe End...\n', () => console.log('All Date was sent'));
    }

    generateMore();
}).listen(3000, () => {
    console.log('server listening 3000');
})

No-Flowing Mode

但还有一种模式No-Flowing Mode,即生产者到了highWaterMark阈值后,消费者才开始消费数据,需要多少取多少,慢慢读。


No-Flowing Mode

Duplex Stream

Duplex Stream

上面说的第三种流模式:双工模式。即实现了可读流又实现了可写流,但它的输入和输出可以没有任何关系。

Transform Stream

Transform Stream

还有一种Transform Stream,它同样具备 Readable 和 Writable 的能力,只不过它的输入和输出是存在相互关联的,中间做了一次转换处理。常见的处理有 Gzip 压缩、解压等。

相关文章

  • nodejs流编程入门

    nodejs中的流 流是什么,应该很好理解,计算机中数据流处处存在。linux的管道设计就是利用了流的概念,所有的...

  • React Native的极简手册

    安装入门 安装入门可以参考:React Native官方文档。 NodeJS知识储备:参考《NodeJS入门》。(...

  • Node入门到入门(Windows)

    Node入门到入门(Windows) 安装NodeJS和NPM 1.安装NodeJS和NPM ​ 打开...

  • nodejs入门

    nodejs入门 花了点时间整理了下nodejs入门的图谱,如果将整个图谱的点都过了一次,相信你的nodejs知识...

  • 搭建区块链技术(go和JavaScript实现)

    技术图: 编程实现:(1)Nodejs/Javascript Nodejs平台强大的网络编程能力,以及js脚本语言...

  • Java编程入门

    Java编程入门(词汇表) Java编程入门:前言 Java编程入门:第1章 思考的风景 Java编程入门(1.1...

  • C++ 快速入门笔记:进阶编程

    C++入门笔记:高级编程 文件和流 打开文件void open (const char *filename, io...

  • NODE.JS

    入门 NODE安装 http://www.runoob.com/nodejs/nodejs-install-set...

  • nodejs 学习路线

    <1--nodejs入门> 1.准备-- js语言入门: -- JavaScript 教程 ...

  • 库&插件&框架&工具

    nodejs 入门 nodejs 入门教程,大家可以在 github 上提交错误2016 年最好用的表单验证库 S...

网友评论

      本文标题:nodejs流编程入门

      本文链接:https://www.haomeiwen.com/subject/gxhdrqtx.html