转换流
在数据流经管道时修改数据。
转换流 是 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 反馈 — 无需本地设置。