node中流的理解

前言

对于前端同学来讲流的概念还是不太好理解的。然而stream模块是node中一个非常重要的模块。

  • node官方文档上是这么描述的:流(stream)是一种在 Node.js 中处理流式数据的抽象接口
    那我们姑且这么理解吧:流就是为我们提供了一套处理数据的工具。

为什么要使用流

既然流是一种处理数据的工具,那肯定还有其他的工具可以供我们使用啊,那为什么我们非要用流来处理呢?或者说使用流能有啥好处?话不多说,上代码:

const path = require('path')
const http = require('http')
const fs = require('fs')
http.createServer((req, res) => {
    fs.readFile(path.resolve(__dirname, 'src/data.txt'), (err, data) => {
        if (!err) {
            res.setHeader('Content-Type', 'text/plain;charset=utf-8') // 设置编码
            res.end(data)
        }
    })
}).listen(8888)
复制代码

上面的代码看着貌似没有问题。假设我们读取的不是一个.txt的文件,而是一个.mp4格式的视频呢?实际上我们读取的数据会存放在内存中,那上面的代码就会大量消耗内存。那有没有什么办法解决呢?这个时候,流这个工具就派上用场啦,他可以实现把资源一块一块的往内存中运输,然后在一块一块的从内存中取出来。这样就不会出现一次性把文件都放入内存中啦。

node中四种基本流类型

node中提供了四种基本的流类型分别是:

  • Readable - 可读的流 (例如 fs.createReadStream()).
  • Writable - 可写的流 (例如 fs.createWriteStream()).
  • Duplex - 可读写的流 (例如 net.Socket).
  • Transform - 在读写过程中可以修改和变换数据的 Duplex 流(例如zlib.createDeflate())

我们这里只讨论可读流和可写流。

可读流

可读流有两种模式:

流动模式

从系统底层读取数据并push()到缓存池,达到highWaterMark后 push() 返回 false,资源停止流向缓存池,并触发data事件消费数据。

切换到Flowing模式的方法:

  • 监听data事件
  • 调用stream.resume()方法
  • 调用stream.pipe()方法将数据发送到 Writable
暂停模式

Stream 默认是Paused模式,必须显式调用stream.read()方法来从流中读取数据。每一次数据达到缓存池都会触发一次 readable 事件,也就是每一次 push() 都会触发 readable。

切换到Paused模式的方法:

  • 监听readable事件
  • 如果不存在管道目标(pipe destination),调用 stream.pause()
  • 如果存在管道目标,取消 data 事件监听,并调用 stream.unpipe() 方法移除所有管道

我们前言部分的代码就可以稍稍改造一下啦!

const path = require('path')
const fs = require('fs')
const http = require('http')

http.createServer((req, res) => {
    fs.createReadStream(path.resolve(__dirname, 'src/data.txt'))
})
复制代码

可写流

原理与 Readable Stream 是比较相似的,数据流过来的时候,会直接写入到资源池,当写入速度比较缓慢或者写入暂停时,数据流会进入队列池缓存起来

当生产者写入速度过快,把队列池装满了之后,就会出现「背压」,这个时候是需要告诉生产者暂停生产的,当队列释放之后,Writable Stream 会给生产者发送一个 drain 消息,让它恢复生产。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值