Fetch Streaming Response Backpressure
Read a fetch response body as a stream with manual reader control, honoring backpressure so a slow consumer cannot balloon memory.
Code
// stream the response body incrementally so backpressure applies
async function downloadWithProgress(url, onProgress, chunkPauseMs = 0) {
const res = await fetch(url);
if (!res.ok || !res.body) throw new Error('download failed: ' + res.status);
const total = Number(res.headers.get('content-length') ?? 0);
const reader = res.body.getReader();
let received = 0;
const parts = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
parts.push(value);
received += value.length;
if (onProgress && total > 0) {
onProgress(received, total);
}
if (chunkPauseMs > 0) {
// 消费变慢时读取循环自然放慢,读取暂停即向上游传导背压
await new Promise((r) => setTimeout(r, chunkPauseMs));
}
}
const blob = new Blob(parts);
return { bytes: received, total, blob };
}
const result = await downloadWithProgress(
'https://cdn.example.com/dataset.bin',
(got, total) => console.log('progress:', Math.round((got / total) * 100) + '%'),
10,
);
console.log('downloaded', result.bytes, 'of', result.total, 'bytes');Report a problem with this exampleOpens a pre-filled issue on GitHub.