前端都是事件响应机制。发送个请求,返回结果后通过某个事件的回调函数处理。如果需要返回的数据太大,则需要一直等待。通过Stream,就能返回一部分,就解析一部分,显示一部分。可以优化体验。
fetch API返回的response.body是一个 ReadableStream
对象。ReadableStream对请求大体积文件时非常有用,可以让应答数据,一小段一小段的解析。Web Stream应该是为网络视频,网络直播专门开放的API。
1 | // fetch函数是立刻返回一个promise,当HTTP Header的应答到来时,就进入then函数 |
这样就是通过对fetch取回的response.body,可以做流式处理,对视频,图片,大文件都有好处,至少能显示进度了。
也可以创建自定义的ReadableStream。ReadableStream在创建时,需要提供underlying source,就是数据源对象。在规范文档中,对source分为push source,和pull source。比如websocket属于push source,而读取文件算是pull source。在规范文档中都有例子。
1 | var stream = new ReadableStream( |
但是这里有几个地方值得注意,规范中貌似没有写清楚,这些内部机制不理解导致很多代码看不懂:
- start函数会立即执行
- pull函数会在start函数立即执行
- 如果start函数返回一个promise对象,则pull函数不再执行,而是等promise对象resolve以后才开始执行pull函数
- chunk data可以通过controller.enqueue放入ReadableStream的内部队列中,每次enqueue,都会触发pull函数
- 如果pull函数,返回一个promise,则不会每次enqueue都触发pull函数
在pdf.js的代码中,main线程和worker线程之间通过stream,传递pdf数据,很多利用了ReadableStream的特性,这些特性的教程很少。理解起来挺费劲。
优秀参考: