0Pricing
JavaScript Academy · 课时

转换流

在数据流经管道时修改数据。

转换流 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。

什么是 TransformStream

TransformStream 位于可读端和可写端之间。写入其中的数据块会经过转换后输出,相当于一个可以实时映射、筛选或重塑数据的管线阶段。

结构

它有两个端:writable(数据从这里输入)和 readable(转换后的数据从这里输出)。

const ts = new TransformStream();
console.log(ts.writable, ts.readable);

转换方法

使用 transform(chunk, controller) 函数定义行为。调用 controller.enqueue() 来输出数据。

const upper = new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(chunk.toUpperCase());
  }
});

输入一个,输出多个

一次转换可以针对一个输入输出零个、一个或多个数据块,非常适合拆分或扩展数据。

const splitter = new TransformStream({
  transform(line, controller) {
    for (const word of line.split(" ")) controller.enqueue(word);
  }
});

使用转换进行筛选

只需不要 enqueue 您想要丢弃的数据块即可。

const onlyEven = new TransformStream({
  transform(n, controller) {
    if (n % 2 === 0) controller.enqueue(n);
  }
});

刷新方法

flush(controller) 会在输入结束时运行一次,非常适合输出缓冲区中剩余的数据或最后一个数据块。

const ts = new TransformStream({
  transform(c, ctrl) { ctrl.enqueue(c); },
  flush(ctrl) { ctrl.enqueue("[END]"); }
});

跨数据块缓冲

将状态保存在闭包中,以便合并不完整的数据块,例如从任意字节边界组装完整的行。

let buffer = "";
new TransformStream({
  transform(chunk, ctrl) {
    buffer += chunk;
    const parts = buffer.split("\n");
    buffer = parts.pop();
    for (const line of parts) ctrl.enqueue(line);
  },
  flush(ctrl) { if (buffer) ctrl.enqueue(buffer); }
});

内置转换流

平台提供了 TextDecoderStream、TextEncoderStream、CompressionStream/DecompressionStream,这些都是现成的转换流。

const gzip = new CompressionStream("gzip");
const compressed = inputStream.pipeThrough(gzip);

通过 pipeThrough 连接

readable.pipeThrough(transform) 会将来源连接到转换流,并返回转换流的可读输出,以便连接到下一个阶段。

const out = sourceStream
  .pipeThrough(new TextDecoderStream())
  .pipeThrough(upper);

异步转换

transform 可以是异步的:您可以在其中使用 await 调用接口,或针对每个数据块执行异步工作。该流会等待承诺对象完成。

new TransformStream({
  async transform(chunk, ctrl) {
    const result = await process(chunk);
    ctrl.enqueue(result);
  }
});

错误传播

在 transform 中抛出错误会使 stream 出错;下游使用方会看到该错误,整个管线也会随之停止。

new TransformStream({
  transform(chunk, ctrl) {
    if (!valid(chunk)) throw new Error("bad chunk");
    ctrl.enqueue(chunk);
  }
});

快速检查

测试转换流。

回顾:转换流

您使用 transform 和 flush 构建了转换流,对数据块进行映射、筛选和展开,跨数据块边界进行缓冲,使用了 CompressionStream 等内置功能,并用 pipeThrough 连接各个阶段。接下来学习:背压与管道传输。

常见问题解答

「转换流」课时是免费的吗?

是的 — 「转换流」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。

「转换流」这节课中我会学到什么?

在数据流经管道时修改数据。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「转换流」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 JavaScript Academy 课中编写并运行代码吗?

能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 可读流
  2. 流式处理 Fetch 响应
  3. 转换流
  4. 背压与管道传输
← 返回 JavaScript Academy