🚰 从小水管到洪流:你真的会用前端 Stream API 吗?
🧠 想象一下:处理 1G 的数据,你还在等它全加载完才开始处理?Stream API 早就能边读边处理,边下边播,效率飞起。
🎬 引子:什么是 Stream?
Stream(流)是指“按块”处理数据的一种方式,而不是等待整个数据加载完成。
在前端中,这个概念越来越重要:
- 🚀 文件上传、下载
- 🎥 视频边下边播
- 📦 大型 JSON 文件解析
- 🧠 AI 接口的流式响应(如 OpenAI)
Stream 就像一个数据的水管:一边输入(ReadableStream),一边输出(WritableStream)。
🧩 Stream API 在浏览器中的核心概念
浏览器中的 Stream API 来自 WHATWG Streams 标准,核心是三个对象:
类型 | 作用 |
---|---|
ReadableStream | 数据源,比如 fetch 响应 |
WritableStream | 数据目标,比如写入文件或 UI |
TransformStream | 中间转换处理,比如解压或转码 |
🧪 实战:用 Stream 边下载边解析一个超大 JSON 文件
💡 场景:你有一个非常大的 JSON 文件(100MB+),直接 response.json()
会内存爆炸。我们可以使用 Stream 一边读取、一边解析。
📦 假设服务返回的是这样的内容:
[{"id":1,"name":"Alice"}, {"id":2,"name":"Bob"}, ...]
我们要实现:
✅ 不一次性加载内存 ✅ 逐个 item 实时处理(例如渲染 UI)
🧰 代码实战:
async function streamJsonArray(url) {
const response = await fetch(url);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
let boundary = buffer.lastIndexOf('}');
if (boundary !== -1) {
const chunk = buffer.slice(0, boundary + 1);
buffer = buffer.slice(boundary + 1);
// 处理 JSON 对象片段
chunk.split('},').forEach(item => {
try {
const json = JSON.parse(item.endsWith('}') ? item : item + '}');
console.log('Parsed Item:', json);
} catch (e) {
// 可能是尾巴不完整,跳过
}
});
}
}
console.log('Stream parsing completed');
}
🔍 小技巧:
- 使用
TextDecoder
是关键,避免二进制乱码; - 处理 JSON 数组需要按
}
拆分并修正; - 这就是典型的“边下载边处理”流式思维!
🌊 其他 Stream 的高级用法一览
📁 文件上传(ReadableStream → fetch)
const fileStream = file.stream(); // File → ReadableStream
fetch('/upload', {
method: 'POST',
body: fileStream
});
🎧 OpenAI API 接口流式响应处理
const response = await fetch('/ai-stream');
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
console.log('AI says:', chunk);
}
🎥 视频边播边缓存(Service Worker + Stream)
在 Service Worker 中劫持 fetch
请求,将视频数据流写入缓存。
🛠️ 浏览器原生支持情况
浏览器 | ReadableStream | WritableStream | TransformStream |
---|---|---|---|
Chrome | ✅ | ✅ | ✅ |
Edge | ✅ | ✅ | ✅ |
Firefox | ✅ | ✅ | ✅ |
Safari | ✅(较新版本) | ✅(较新版本) | ✅ |
🧠 总结:为什么前端要重视 Stream?
- 📉 降低内存消耗,提升用户体验
- ⏱️ 加快处理速度,尤其在网络/文件传输中
- 🧬 适配未来数据流趋势(AI、大文件、直播、微服务)
Stream 不只是后端的玩具,前端也该用起来!
👍 如果你觉得这篇文章有帮助,欢迎点赞、关注、收藏,后续我会努力更新更多的javascript的实用技巧。