如何使用Fetch API按指定chunk大小异步分块读取HTTP响应内容?
Fetch API流式读取响应能力说明
Fetch API完全支持你需要的非阻塞按块处理响应内容的能力,核心是基于其内置的ReadableStream流式响应接口。
核心实现逻辑
你给出的示例代码已经是核心实现的雏形,这里补充几个关键说明:
fetch请求返回的Response.body是标准的可读流对象,调用getReader()方法可以获取流的默认读取器,不需要等待完整响应下载完成就可以开始读取内容。reader.read()方法返回Promise,等待Chunk就绪的过程完全非阻塞,不会占用主线程,你可以在等待期间正常执行其他任务。- 注意:标准规范中
reader.read()不接收自定义大小参数,每次调用返回的是当前流已经加载完成的可用数据块,如果你需要固定大小的自定义Chunk,可以自行维护缓冲区做拼接切分。
完整自定义大小Chunk实现示例
/** * 按自定义Chunk大小非阻塞读取响应内容 * @param {string} url 请求目标地址 * @param {number} CHUNK_SIZE 自定义Chunk大小,默认1MB */ async function readByCustomChunk(url, CHUNK_SIZE = 1024 * 1024) { const response = await fetch(url) // 校验响应合法性 if (!response.ok || !response.body) { throw new Error('请求失败或响应无可读内容') } const reader = response.body.getReader() // 内部缓冲区,用于拼接小块数据到自定义大小 let buffer = new Uint8Array(0) while (true) { const { done, value } = await reader.read() // 流读取完成时退出循环 if (done) break // 将新读取到的内容合并到缓冲区 buffer = new Uint8Array([...buffer, ...value]) // 缓冲区长度满足自定义Chunk大小时,切分处理 while (buffer.length >= CHUNK_SIZE) { const customChunk = buffer.slice(0, CHUNK_SIZE) // 此处编写你的Chunk处理逻辑 processChunk(customChunk) // 缓冲区保留剩余未处理的内容 buffer = buffer.slice(CHUNK_SIZE) } } // 流读取完成后,缓冲区剩余的不足指定大小的内容作为最后一个Chunk处理 if (buffer.length > 0) { processChunk(buffer) } }
核心特性说明
- 非阻塞:读取过程为异步执行,不会阻塞页面渲染、用户交互等其他主线程任务
- 灵活可控:可随时调用
reader.cancel()中止流读取,提前终止请求,不需要等待完整响应下载完成 - 低内存占用:不需要将完整响应内容全部存入内存,适合大文件下载、实时数据流处理等场景
内容的提问来源于stack exchange,提问作者Lufftre
相关产品推荐
相关产品推荐

