Fetch streams 很棒,但并不适合用来测量上传/下载进度

Part of my role at Mozilla is making sure we're focusing on the right features, and we got onto the topic of fetch upload streams. It's something Chrome has supported for a while, but it isn't yet supported in either Firefox or Safari.

我在 Mozilla 的部分职责是确保我们专注于正确的功能,我们谈到了 fetch 上传流。Chrome 已经支持了一段时间,但 Firefox 和 Safari 尚未支持。

I asked folks on various social platforms what they thought of the feature, and what they'd use it for. The most common answer by far was "to measure upload progress", but… using it for that will give inaccurate results, and may even lead to bad implementations in browsers.

我在多个 社交 平台上询问大家对这个特性的看法以及会用它来做什么。最常见的回答就是“用来测量上传进度”,但……把它用于此目的会得到不准确的结果,甚至可能导致浏览器实现上的不良设计。

Let's dig in…

让我们深入探讨……

Response streams

Response streams

Streaming responses have been available in all browsers for years now:

流式响应已在所有浏览器中可用多年:

const response = await fetch(url);
const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; console.log(value);
} console.log('Done!');

This lets you get the response chunk-by-chunk, so you can start processing it as you receive it.

这让你可以逐块获取响应,从而在接收的同时开始处理。

This is even easier with async iterators:

使用 async 迭代器甚至更简单:

const response = await fetch(url); for await (const chunk of response.body) { console.log(chunk);
} console.log('Done!');

…but that isn't supported in Safari. I've proposed it for interop 2026.

……但 Safari 并不支持。我已经提议将其纳入 2026 年的互操作计划

The chunks are Uint8Arrays, but you can use TextDecoderStream to get the chunks as text.

这些分块是 Uint8Array,但你可以使用 TextDecoderStream 把它们转成文本。

const response = await fetch(url);
const textStream = response.body.pipeThrough(new TextDecoderStream());

But they're not ideal for measuring download progress

但它们并不适合测量下载进度

You could try to measure download progress like this:

你可以尝试这样测量下载进度:


const response = await fetch(url);
const contentLength = Number(response.headers.get('Content-Length')) || 0;
let downloaded = 0; for await (const chunk of response.body) { downloaded += chunk.length; if (contentLeng...
开通本站会员,查看完整译文。

首页 - Wiki
Copyright © 2011-2025 iteam. Current version is 2.146.0. UTC+08:00, 2025-09-22 03:15
浙ICP备14020137号-1 $访客地图$