nodejs-用数据流-v1.0.0

它是什么

通过继承eventEmitter,实现异步操作;使用buffer使用实现读一部分写一部分(缓存功能),并且操作的是binary。

为什么要

读写大数据时:异步读写,避免堵塞,避免卡顿。

如何使用

模块概览
nodejs的核心模块,基本上都是stream的的实例,比如process.stdout、http.clientRequest。

对于大部分的nodejs开发者来说,平常并不会直接用到stream模块,只需要了解stream的运行机制即可(非常重要)。

而对于想要实现自定义stream实例的开发者来说,就得好好研究stream的扩展API了,比如gulp的内部实现就大量用到了自定义的stream类型。

const fs = require('fs');

fs.createReadStream('./sample.txt').pipe(process.stdout);

流的分类
在nodejs中,有四种stream类型:

Readable:数据可读,比如 fs.createReadStream()。
Writable:数据可写,比如 fs.createWriteStream()。
Duplex:可读可写,比如 net.Socket()。
Transform:数据可改,比如 zlib.createDeflate()(数据压缩/解压)。

常见的流

#数据可读:
http.IncomingRequest
fs.createReadStream()
process.stdin

#数据可写:
var fs = require('fs');
var filepath = './sample.txt';
var writeStram = fs.createWriteStream(filepath);

#可读可写:
net.Socket

#数据可改:
var zlib = require('zlib');
zlib.createGzip()

基本架构

# 引入类库
const { Duplex,Transform } = require('stream');

# 流的创建
#2 建双共流
class YmcDuplex extends Duplex {
  constructor(options) {
    super(options);
    // ...
  }

  _write(chunk, encoding, callback) {
    console.log('we write: ', chunk);
    callback();
  }

  _read(size) {
    this.push('read method');
    this.push(null);
  }
}
#2 建可改流
class YmcTransform extends Transform {
  constructor(options) {
    super(options);
  }
  _transform(chunk, encoding, done) {
    const upperChunk = chunk.toString().toUpperCase()
    this.push(upperChunk)
    done()
  }
  _flush(cb){
    /* at the end, output the our additional info */
    this.push('this is flush data\n')
    cb(null, 'appending more data\n')
  }
}


# 流的操作
#2 操双功流
#3 创建实例
const dp = new YmcDuplex({
  readableObjectMode: true
})
#3 设置事件
#4 接收数据时执行
dp.on('data', (chunk) => {
  console.log('we read: ', chunk)
})
#4 写入数据
dp.write('write method', 'utf-8')

#2 操可改流
#3 创建实例
const tss = new YmcTransform()
#3 接收数据
tss.pipe(process.stdout)
#3 写入数据
tss.write('hello transform stream\n')
tss.write('another line\n')
#3 写入结束
tss.end()

文件操作

# 引入类库
let fs = require("fs");

# 缓存数据
let data = '';

# 流的创建
#2 建可读流
let readerStream = fs.createReadStream('input.txt');

#流的操作
#2 操可读流
#3 设置编码
readerStream.setEncoding('UTF8');
#3 设置事件:data, end, and error
#4 收到数据时执行
readerStream.on('data', function(chunk) {
   data += chunk;
});
#4 收完数据时执行
readerStream.on('end',function(){
   console.log(data);
});
#4 出现错误时执行
readerStream.on('error', function(err){
   console.log(err.stack);
});

某些语糖

#管道操作
readerStream.pipe(writerStream);
一些思考

01.如何避免回调地狱
既然基于事件模式,那么当代码越复杂时,越容易走进回调地狱(何时出现回调地狱)。那么该如何避免呢?这是一种解决方案——将回调模式/事件模式转化为允诺模式(一点金光.它允诺化.jianshu)。

参考文献

chyingp.nodejs-learning-stream[P].cnblogs
runoob.nodejs-stream[P].runoob
斗米.Duplex-Stream-Transform-Stream[p].juejin
nodejs.offical-docs-srteam[p].
饥人谷.深入理解nodejs Stream模块[p].jianshu
wanghui-garcia."nodejs-stream部分".cnblogs

你可能感兴趣的:(nodejs-用数据流-v1.0.0)