stream/promises.pipeline
stream/promises.pipeline conecta Readable → Transform → Writable com propagação de erros correta, destruição de stream em caso de falha e uma API de Promise adequada para manipuladores async/await.
Busque em todas as páginas da documentação
stream/promises.pipeline conecta Readable → Transform → Writable com propagação de erros correta, destruição de stream em caso de falha e uma API de Promise adequada para manipuladores async/await.
import { pipeline } from 'node:stream/promises';
import { createReadStream, createWriteStream } from 'node:fs';
import { createGzip } from 'node:zlib';
await pipeline(
createReadStream('input.log'),
createGzip(),
createWriteStream('input.log.gz'),
);Quando usar isso:
.on('error') em pipes manuaisimport { pipeline } from 'node:stream/promises';
import { createReadStream } from 'node:fs';
import { createServer } from 'node:http';
import { Transform } from 'node:stream';
import { createGzip } from 'node:zlib';
const lineCount = new Transform({
transform(chunk, _enc, cb) {
const lines = String(chunk).split('\n').length - 1;
(this as Transform & { lines?: number }).lines =
((this as Transform & { lines?: number }).lines ?? 0) + lines;
cb(null, chunk);
},
});
const server = createServer(async (req, res) => {
if (req.url !== '/export') {
res.writeHead(404).end();
return;
}
try {
res.writeHead(200, {
'content-type': 'application/gzip',
'content-disposition': 'attachment; filename="export.log.gz"',
});
await pipeline(
createReadStream('app.log'),
lineCount,
createGzip(),
res,
);
console.log('linhas processadas', (lineCount as Transform & { lines?: number }).lines);
} catch (err) {
if (!res.headersSent) res.writeHead(500);
res.end();
console.error('pipeline falhou', err);
}
});
server.listen(3000);O que isso demonstra:
pipeline aceita res HTTP Writable como destino finalheadersSent exigem o encerramento da resposta sem uma segunda linha de statusawait integra-se com try/catch como qualquer I/O assíncronopipeline destrói os streams participantes com o erro.end.node:stream - a variante Promise é preferida em código async.| Recurso | pipeline | pipe manual |
|---|---|---|
| Encaminhamento de Erro | Sim | Manual |
| Destruir em caso de falha | Sim | Manual |
| API de Promise | Sim | Não |
| AbortSignal | Sim | Manual |
import { pipeline } from 'node:stream/promises';
import type { Readable, Writable } from 'node:stream';
export async function safePump(
source: Readable,
sink: Writable,
signal?: AbortSignal,
): Promise<void> {
await pipeline(source, sink, { signal });
}writeHead antes de pipeline para o destino da resposta. Correção: defina os cabeçalhos primeiro.req.on('aborted') opcionalmente. Correção: passe AbortSignal vinculado à requisição._flush para dados em buffer pendentes.| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
finished + destroy manual | Código de streams legado | Projetos novos |
pump (npm) | Versões mais antigas do Node | Node 24 tem pipeline nativo |
| Bufferar carga útil inteira | Arquivos pequenos < 1 MB | Downloads grandes |
Web pipeThrough | Streams Web do fetch | Fontes node:fs |
Sim - em caso de sucesso ou falha, os streams participantes são destruídos/encerrados apropriadamente.
Sim - argumentos variádicos: pipeline(a, b, c, d, sink).
Passe a opção { signal: abortController.signal } no pipeline do Node 24.
ENOENT em arquivo ausente, ECONNRESET em desconexão do cliente, erros zlib em gzip corrompido.
API de callback legado - a versão Promise é preferida em manipuladores async.
Sim - os dados fluem da esquerda para a direita através de cada Transform.
Todos os streams na cadeia devem concordar sobre modo objeto vs byte (com uma Transform de conversão).
Use um stream de "tap" PassThrough no meio contando chunk.length.
Mesmo padrão - await pipeline(source, res) dentro de uma rota async com um wrapper de erro.
Use reply.send(stream) ou pipeline para a resposta bruta conforme a documentação do Fastify 5 para controle fino.
Use stream/consumers.buffer ou um Writable que coleta chunks na memória para asserções.
Herdado da semântica de stream - pipeline não remove a necessidade de um highWaterMark sensato.
Versões da Pilha: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026