Fetch body、克隆与消费
Response body 是一次性流。json()、text() 和 reader 都会消费它;需要两个消费者时,必须在第一次消费前调用 clone()。
最小实验:一次消费与克隆
js
const response = new Response(JSON.stringify({ ok: true }), {
headers: { 'content-type': 'application/json' }
})
const copy = response.clone()
const [data, raw] = await Promise.all([response.json(), copy.text()])
console.log(data.ok, raw.length)
try {
await response.text()
} catch (error) {
console.log('second read:', error.name)
}预期第一次并行消费成功,最后一次读取失败,因为原始 body 已被 json() 锁定。删除 clone() 后再运行,第二个消费者应失败。复制响应不会复制服务器请求,两个分支还可能产生不同的消费速度和内存压力。
机制与边界
需要增量处理时使用 response.body.getReader(),每次读取 chunk 并在结束或取消时释放 reader。取消 reader 不能保证服务器撤回已经发送的字节;大文件应考虑背压、取消和缓存策略。
练习
- 用
ReadableStream构造三个 chunk,记录 reader 的done/value变化。 - 读取到第二个 chunk 后调用
reader.cancel(),说明哪些资源已经释放、哪些网络副作用无法撤回。 - 比较
clone()两个完整 body 与只解析一次后共享结果的内存代价。