2025年读取bytebuffer里的内容(readablebytechannel 读取byte)

读取bytebuffer里的内容(readablebytechannel 读取byte)svg xmlns http www w3 org 2000 svg style display none svg

大家好,我是讯享网,很高兴认识大家。




讯享网

                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                <p>JavaScript 编程逻辑很多时候会将访问网络作为原子操作&#xff0c;比如请求是同时创建和发送的&#xff0c;响应数<br /> 据也是以统一的格式一次性暴露出来的。这种约定隐藏了底层的混乱&#xff0c;让涉及网络的代码变得很清晰。<br /> 从TCP/IP 角度来看&#xff0c;传输的数据是以分块形式抵达端点的&#xff0c;而且速度受到网速的限制。接收端点<br /> 会为此分配内存&#xff0c;并将收到的块写入内存。Fetch API 通过ReadableStream 支持在这些块到达时就实<br /> 时读取和操作这些数据。<br /> 正如Stream API所定义的&#xff0c;ReadableStream 暴露了getReader()方法&#xff0c;用于产生ReadableStream-<br /> DefaultReader&#xff0c;这个读取器可以用于在数据到达时异步获取数据块。数据流的格式是Uint8Array。<br /> 下面的代码调用了读取器的read()方法&#xff0c;把最早可用的块打印了出来&#xff1a;<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then((body) &#61;&gt; {<br /> let reader &#61; body.getReader();<br /> console.log(reader); // ReadableStreamDefaultReader {}<br /> reader.read()<br /> .then(console.log);<br /> });<br /> // { value: Uint8Array{}, done: false }<br /> 在随着数据流的到来取得整个有效载荷&#xff0c;可以像下面这样递归调用read()方法&#xff1a;<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then((body) &#61;&gt; {<br /> let reader &#61; body.getReader();<br /> function processNextChunk({value, done}) {<br /> if (done) {<br /> return;<br /> }<br /> console.log(value);<br /> return reader.read()<br /> .then(processNextChunk);<br /> }<br /> return reader.read()<br /> .then(processNextChunk);<br /> });<br /> // { value: Uint8Array{}, done: false }<br /> // { value: Uint8Array{}, done: false }<br /> // { value: Uint8Array{}, done: false }<br /> // …<br /> 异步函数非常适合这样的fetch()操作。可以通过使用async/await 将上面的递归调用打平&#xff1a;<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then(async function(body) {<br /> let reader &#61; body.getReader();<br /> while(true) {<br /> let { value, done } &#61; await reader.read();<br /> if (done) {<br /> break;<br /> }<br /> console.log(value);<br /> }<br /> });<br /> // { value: Uint8Array{}, done: false }<br /> // { value: Uint8Array{}, done: false }<br /> // { value: Uint8Array{}, done: false }<br /> // …<br /> 另外&#xff0c;read()方法也可以真接封装到Iterable 接口中。因此就可以在for-await-of 循环中方<br /> 便地实现这种转换&#xff1a;<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then(async function(body) {<br /> let reader &#61; body.getReader();<br /> let asyncIterable &#61; {<br /> Symbol.asyncIterator {<br /> return {<br /> next() {<br /> return reader.read();<br /> }<br /> };<br /> }<br /> };<br /> for await (chunk of asyncIterable) {<br /> console.log(chunk);<br /> }<br /> });<br /> // { value: Uint8Array{}, done: false }<br /> // { value: Uint8Array{}, done: false }<br /> // { value: Uint8Array{}, done: false }<br /> // …<br /> 通过将异步逻辑包装到一个生成器函数中&#xff0c;还可以进一步简化代码。而且&#xff0c;这个实现通过支持只读<br /> 取部分流也变得更稳健。如果流因为耗尽或错误而终止&#xff0c;读取器会释放锁&#xff0c;以允许不同的流读取器继续<br /> 操作&#xff1a;<br /> async function* streamGenerator(stream) {<br /> const reader &#61; stream.getReader();<br /> try {<br /> while (true) {<br /> const { value, done } &#61; await reader.read();<br /> if (done) {<br /> break;<br /> }<br /> yield value;<br /> }<br /> } finally {<br /> reader.releaseLock();<br /> }<br /> }<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then(async function(body) {<br /> for await (chunk of streamGenerator(body)) {<br /> console.log(chunk);<br /> }<br /> });<br /> 在这些例子中&#xff0c;当读取完Uint8Array 块之后&#xff0c;浏览器会将其标记为可以被垃圾回收。对于需要在<br /> 不连续的内存中连续检查大量数据的情况&#xff0c;这样可以节省很多内存空间。<br /> 缓冲区的大小&#xff0c;以及浏览器是否等待缓冲区被填充后才将其推到流中&#xff0c;要根据JavaScript 运行时的<br /> 实现。浏览器会控制等待分配的缓冲区被填满&#xff0c;同时会尽快将缓冲区数据&#xff08;有时候可能未填充数据&#xff09;发<br /> 送到流。<br /> 不同浏览器中分块大小可能不同&#xff0c;这取决于带宽和网络延迟。此外&#xff0c;浏览器如果决定不等待网络&#xff0c;<br /> 也可以将部分填充的缓冲区发送到流。最终&#xff0c;我们的代码要准备好处理以下情况&#xff1a;<br />  不同大小的Uint8Array 块&#xff1b;<br />  部分填充的Uint8Array 块&#xff1b;<br />  块到达的时间间隔不确定。<br /> 默认情况下&#xff0c;块是以Uint8Array 格式抵达的。因为块的分割不会考虑编码&#xff0c;所以会出现某些值作<br /> 为多字节字符被分散到两个连续块中的情况。手动处理这些情况是很麻烦的&#xff0c;但很多时候可以使用<br /> Encoding API 的可插拔方案。<br /> 要将Uint8Array 转换为可读文本&#xff0c;可以将缓冲区传给TextDecoder&#xff0c;返回转换后的值。通过设<br /> 置stream: true&#xff0c;可以将之前的缓冲区保留在内存&#xff0c;从而让跨越两个块的内容能够被正确解码&#xff1a;<br /> let decoder &#61; new TextDecoder();<br /> async function* streamGenerator(stream) {<br /> const reader &#61; stream.getReader();<br /> try {<br /> while (true) {<br /> const { value, done } &#61; await reader.read();<br /> if (done) {<br /> break;<br /> }<br /> yield value;<br /> }<br /> } finally {<br /> reader.releaseLock();<br /> }<br /> }<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then(async function(body) {<br /> for await (chunk of streamGenerator(body)) {<br /> console.log(decoder.decode(chunk, { stream: true }));<br /> }<br /> });<br /> // &lt;!doctype html&gt; …<br /> // whether a &lt;a data-link-type&#61;“dfn” href&#61;“#concept-header” …<br /> // result to <var>rangeValue</var>. …<br /> // …<br /> 因为可以使用ReadableStream 创建Response 对象&#xff0c;所以就可以在读取流之后&#xff0c;将其通过管道<br /> 导入另一个流。然后在这个新流上再使用Body 的方法&#xff0c;如text()。这样就可以随着流的到达实时检<br /> 查和操作流内容。下面的代码展示了这种双流技术&#xff1a;<br /> fetch(‘https://fetch.spec.whatwg.org/’)<br /> .then((response) &#61;&gt; response.body)<br /> .then((body) &#61;&gt; {<br /> const reader &#61; body.getReader();<br /> // 创建第二个流<br /> return new ReadableStream({<br /> async start(controller) {<br /> try {<br /> while (true) {<br /> const { value, done } &#61; await reader.read();<br /> if (done) {<br /> break;<br /> }<br /> // 将主体流的块推到第二个流<br /> controller.enqueue(value);<br /> }<br /> } finally {<br /> controller.close();<br /> reader.releaseLock();<br /> }<br /> }<br /> })<br /> })<br /> .then((secondaryStream) &#61;&gt; new Response(secondaryStream))<br /> .then(response &#61;&gt; response.text())<br /> .then(console.log);<br /> // &lt;!doctype html&gt; …</p>

讯享网
小讯
上一篇 2025-04-30 08:59
下一篇 2025-06-03 12:51

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/179142.html