关于 Javascript 中 stream 的一些疑惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
yezheyu
V2EX    程序员

关于 Javascript 中 stream 的一些疑惑

  •  a href="Javascript:" Onclick="downVoteTopic(928691);" class="vote">
  •   yezheyu 2023-03-31 10:24:34 +08:00 2020 次点击
    这是一个创建于 925 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习 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     Solana     2669 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 13:38 PVG 21:38 LAX 06:38 JFK 09:38
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86