javascript基础从小白到高手系列一百九十九:Streams API

Streams API 是为了解决一个简单但又基础的问题而生的:Web 应用如何消费有序的小信
息块而不是大块信息?这种能力主要有两种应用场景。
 大块数据可能不会一次性都可用。网络请求的响应就是一个典型的例子。网络负载是以连续信
息包形式交付的,而流式处理可以让应用在数据一到达就能使用,而不必等到所有数据都加载
完毕。
 大块数据可能需要分小部分处理。视频处理、数据压缩、图像编码和JSON 解析都是可以分成小
部分进行处理,而不必等到所有数据都在内存中时再处理的例子。
第24 章在讨论网络请求和远程资源时会介绍Streams API 在fetch()中的应用,不过Streams API
本身是通用的。实现Observable 接口的JavaScript 库共享了很多流的基础概念。
理解流
提到流,可以把数据想像成某种通过管道输送的液体。JavaScript 中的流借用了管道相关的概念,
因为原理是相通的。根据规范,“这些API 实际是为映射低级I/O 原语而设计,包括适当时候对字节流
的规范化”。Stream API 直接解决的问题是处理网络请求和读写磁盘。
Stream API 定义了三种流。
 可读流:可以通过某个公共接口读取数据块的流。数据在内部从底层源进入流,然后由消费者
(consumer)进行处理。
 可写流:可以通过某个公共接口写入数据块的流。生产者(producer)将数据写入流,数据在内
部传入底层数据槽(sink)。
 转换流:由两种流组成,可写流用于接收数据(可写端),可读流用于输出数据(可读端)。这
两个流之间是转换程序(transformer),可以根据需要检查和修改流内容。
块、内部队列和反压
流的基本单位是块(chunk)。块可是任意数据类型,但通常是定型数组。每个块都是离散的流片段,
可以作为一个整体来处理。更重要的是,块不是固定大小的,也不一定按固定间隔到达。在理想的流当
中,块的大小通常近似相同,到达间隔也近似相等。不过好的流实现需要考虑边界情况。
前面提到的各种类型的流都有入口和出口的概念。有时候,由于数据进出速率不同,可能会出现不
匹配的情况。为此流平衡可能出现如下三种情形。
 流出口处理数据的速度比入口提供数据的速度快。流出口经常空闲(可能意味着流入口效率较
低),但只会浪费一点内存或计算资源,因此这种流的不平衡是可以接受的。
 流入和流出均衡。这是理想状态。
 流入口提供数据的速度比出口处理数据的速度快。这种流不平衡是固有的问题。此时一定会在
某个地方出现数据积压,流必须相应做出处理。
流不平衡是常见问题,但流也提供了解决这个问题的工具。所有流都会为已进入流但尚未离开流的
块提供一个内部队列。对于均衡流,这个内部队列中会有零个或少量排队的块,因为流出口块出列的速度与流入口块入列的速度近似相等。这种流的内部队列所占用的内存相对比较小。
如果块入列速度快于出列速度,则内部队列会不断增大。流不能允许其内部队列无限增大,因此它
会使用反压(backpressure)通知流入口停止发送数据,直到队列大小降到某个既定的阈值之下。这个阈
值由排列策略决定,这个策略定义了内部队列可以占用的最大内存,即高水位线(high water mark)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值