【问题标题】:Understanding Javascript Streams, basic example question了解 Javascript 流,基本示例问题
【发布时间】:2022-12-15 02:35:52
【问题描述】:

语境

在我目前的理解中,ReadableStream 构造函数允许您将大块数据分成较小的块(块),然后您可以读取这些块。

fetch 的情况下,您已经准备好使用 ReadableStream,即数据已经成块,并且可以在响应的 body 中找到。但我们可能还想产生一个流(供其他人消费。)

这种用例是用户上传的任何非常大的文件,必须分段处理。


所以疑问是 start 运行同步或异步代码之间的区别是什么,如下所示。

基本语法和示例(使用var 在控制台中轻松复制/粘贴):

var u8View = new Uint8Array(30); //typed array with 30 zeros.

var stream = new ReadableStream({
  start(controller) {
    // to an approx. this will create an "array of chunks" from u8View that a user can access later
    controller.enqueue(u8View)
    controller.close()
  }
})

stream.getReader().read().then(d => console.log(d))


var stream1 = new ReadableStream({
  start(controller) {
    setTimeout(() => {
      controller.enqueue(u8View)
      controller.close()
    }, 1000)
  }
})

stream1.getReader().read().then(d => console.log(d))  

您会注意到代码基本上做同样的事情。

我相信这是因为 read 只有在满足(解决或拒绝)后才传递值。 I take this from a comment in the MDN's example

  • 这是正确的吗?
  • 为什么我觉得这很奇怪,这只是一种常见/预期的行为吗?
  • 所以只要您确保 enqueue 某些内容,您如何处理代码并不重要(即使循环遍历块)?

【问题讨论】:

    标签: javascript browser


    【解决方案1】:

    首先,read 函数解析为包含块值的特殊对象和指示最后一个块的 done 标志。所以如果你想消费整个流,你应该正确处理done标志。

    var reader = stream.getReader();
    reader.read().then(function processChunk({done, value}) {
       console.log('chunk value:', value);
       if (done) {
         console.log('stream closed!');
         return;
       }
       // otherwise continue process chunks
       reader.read().then(processChunk);
    });
    

    在你的读者消费者的例子中,只有一个区别streamstream1 之间。对于stream1,读者将在1秒后stream的读者

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      相关资源
      最近更新 更多