Skip to content

Stream

什么是 Stream(流)?

Stream 是一种 逐块处理数据 的方式,而不是一次性加载全部数据。

  • 传统方式(一次性加载):[整个文件 10GB] → 💥 内存爆炸
  • 流式处理(分块加载):[块1 64KB] → [块2 64KB] → [块3 64KB] → ... → ✅ 内存稳定
场景传统方式流式处理
下载 10GB 文件需要 10GB 内存只需 64KB 内存 ✅
AI 对话输出等待全部生成才显示逐字显示 ✅
上传大文件浏览器卡死流畅上传 ✅
视频播放下载完才能播放边下边播 ✅

Stream 的三种类型

ReadableStream(可读流)

用途:从源头读取数据

数据来源

js
// 1.  Fetch 响应体
const response = await fetch('/api/data')
const stream = response.body // ReadableStream

// 2. 文件
const file = document.querySelector('input').files[0]
const stream = file.stream() // ReadableStream

// 3. 手动创建
const stream = new ReadableStream({
  start(controller) {
    controller.enqueue('数据块1')
    controller.enqueue('数据块2')
    controller.close()
  },
})

核心方法

js
const reader = stream.getReader() // 获取读取器
const { done, value } = await reader.read() // 读取数据
await reader.cancel() // 取消读取
reader.releaseLock() // 释放锁

WritableStream(可写流)

用途:向目标 写入数据

数据去向

js
// 1. 文件保存(File System Access API)
const fileHandle = await window.showSaveFilePicker()
const stream = await fileHandle.createWritable() // WritableStream

// 2. 手动创建
const stream = new WritableStream({
  write(chunk) {
    console.log('接收到:', chunk)
  },
  close() {
    console.log('流关闭')
  },
})

核心方法

js
const writer = stream.getWriter() // 获取写入器
await writer.write('数据') // 写入
await writer.close() // 关闭
await writer.abort() // 中止
writer.releaseLock() // 释放锁

TransformStream(转换流)

用途转换数据(同时包含可读端和可写端)

常见用途

js
// 1. 压缩
const compressor = new CompressionStream('gzip')

// 2. 解压
const decompressor = new DecompressionStream('gzip')

// 3. 文本编码
const encoder = new TextEncoderStream()

// 4. 文本解码
const decoder = new TextDecoderStream()

// 5. 自定义转换
const upperCaseTransform = new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(chunk.toUpperCase())
  },
})

核心方法

js
// 使用 pipeThrough 连接转换流
const processedStream = readableStream.pipeThrough(transformStream1).pipeThrough(transformStream2)

三种流的关系

ReadableStream(读取) → TransformStream(转换) → WritableStream(写入)

示例:下载 → 压缩 → 保存

基于 MIT 许可发布