V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yezheyu
V2EX  ›  程序员

关于 JavaScript 中 stream 的一些疑惑

  •  
  •   yezheyu · 2023-03-31 10:24:34 +08:00 · 1642 次点击
    这是一个创建于 603 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习 http ,看到 Transfer-Encoding: chunked 这个 header ,感觉和 JavaScript 中的 stream 很像,但又有些搞不明白的地方,想请教下大家。

    在 http 长连接中,对于响应 body 的数据传输由两种方式:

    • 使用 Content-Length header 标注数据结束位置,来区分一个 tcp 连接中的多个响应
    • 使用流模式,即分块传输(Transfer-Encoding: chunked),把数据分块传输,并在块的起始位置标注块长度,最后一个块长度为 0 ,表示数据结束来区分一个 tcp 连接中的多个响应

    我想问下,按理说不是只有第二种模式下的 response 才部署有 stream 接口吗?为啥使用 fetch api 请求到第一种 response 部署有 stream 接口呢?

    8 条回复    2023-04-05 12:54:34 +08:00
    3dwelcome
        1
    3dwelcome  
       2023-03-31 10:39:18 +08:00
    http 流是一个很宽泛的概念,你比如 jpeg 图片,传了一小半,也可以显示一部分,但他并不是 chunked 格式。

    chunked 格式主要是用来,对应 ajax 里的 readyState 等于 3: processing request 的情况。
    otakustay
        2
    otakustay  
       2023-03-31 11:17:10 +08:00
    content-length 知道也不代表不能流啊,比如我的长度是 30GB ,那总也得按着带宽一点一点流给你吧,流多少用多少也很正常吧,又不能一下子砸出 30GB 过来
    yezheyu
        3
    yezheyu  
    OP
       2023-03-31 13:59:31 +08:00
    @otakustay
    第一种模式,假设是长度是 30g ,传统的处理方式是根据 Content-Length 事先在内存中开辟一个 30g 的 buffer ,等数据把 buffer 填满即意味着 tcp 连接中的这个响应接收完毕,然后再把数据交给业务代码去消费

    而把 Content-Length 的响应改用 stream 模式去消费,接收一块数据,就直接交给业务代码去消费,并记下数据的长度,重复这个过程并累加计算数据长度,直到累加长度等于 30g ,也就意味着 tcp 连接中这个响应接收完毕

    我这样理解对吗?

    所以 JavaScript 中的 stream 只是对消费方式的一种改造,而 http 中的 stream 是对数据的一种组织方式,我这样理解对吗?
    otakustay
        4
    otakustay  
       2023-03-31 22:13:08 +08:00
    @yezheyu #3 是的,就算有 length 也是一个流,从这个流读字节,读到 30g 的字节后停下就行了。http 层面上无论如何都是流,js 这层就是“直接用 stream”还是“stream 在原生 API 内部处理完后变成 buffer 再给你”的区别
    yezheyu
        5
    yezheyu  
    OP
       2023-04-04 17:52:28 +08:00
    @otakustay

    那我换中说法

    JavaScript 中的 stream 接口只是对消费方式的一种改造,把原来那种必须把数据完全接收到 buffer ,再一次消费,改成接收一点消费一点

    而在 http 中不管使用什么方式组织数据发送,都是 http 流模式,因为这是 tcp 赋予的特性。

    对于 Transfer-Encoding: chunked 是才是对数据组织方式一种改造,把数据变成分块传输,并把数据长度由在 header 整体记录,改为让每个数据块自己记录

    这样理解合适吗?
    otakustay
        6
    otakustay  
       2023-04-04 18:28:44 +08:00
    @yezheyu #5 content-length 和 chunked 是“流”的 2 种结构描述方式,你的理解没错。chunked 多浪费一点空间(每个块要存一个长度,最后还有一个长度为 0 的块),但不用提前知道整个流的长度
    otakustay
        7
    otakustay  
       2023-04-04 18:29:06 +08:00
    当然涉及到 content-encoding 以后这里面还是有不少麻烦的小细节的
    yezheyu
        8
    yezheyu  
    OP
       2023-04-05 12:54:34 +08:00
    @otakustay 好的,多谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2635 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:28 · PVG 19:28 · LAX 03:28 · JFK 06:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.