"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Compreendendo os fluxos Node.js: o que, por que e como usá-los

Compreendendo os fluxos Node.js: o que, por que e como usá-los

Publicado em 2024-11-09
Navegar:175

Understanding Node.js Streams: What, Why, and How to Use Them

Node.js Streams são um recurso essencial para lidar com grandes quantidades de dados com eficiência. Ao contrário dos mecanismos tradicionais de entrada-saída, os fluxos permitem que os dados sejam processados ​​em partes, em vez de carregar os dados inteiros na memória, tornando-os perfeitos para lidar com arquivos grandes ou dados em tempo real. Neste artigo, vamos nos aprofundar no que são streams Node.js, por que são úteis, como implementá-los e vários tipos de streams com exemplos detalhados e casos de uso.

O que são fluxos Node.js?

Em termos simples, um fluxo é uma sequência de dados sendo movidos de um ponto para outro ao longo do tempo. Você pode pensar nisso como uma esteira rolante onde os dados fluem peça por peça, em vez de todos de uma vez.

Os fluxos Node.js funcionam de maneira semelhante; eles permitem que você leia e grave dados em pedaços (em vez de todos de uma vez), tornando-os altamente eficientes em termos de memória.

Streams em Node.js são construídos sobre EventEmitter, tornando-os orientados a eventos. Alguns eventos importantes incluem:

  • data: Emitido quando os dados estão disponíveis para consumo.
  • end: Emitido quando não há mais dados disponíveis para consumo.
  • erro: Emitido quando ocorre um erro durante a leitura ou gravação.

Por que usar fluxos?

Streams oferecem diversas vantagens sobre métodos tradicionais como fs.readFile() ou fs.writeFile() para lidar com E/S:

  1. Eficiência de memória: você pode lidar com arquivos muito grandes sem consumir grandes quantidades de memória, pois os dados são processados ​​em pedaços.
  2. Desempenho: Streams fornecem E/S sem bloqueio. Eles permitem a leitura ou gravação de dados peça por peça, sem esperar que toda a operação seja concluída, tornando o programa mais responsivo.
  3. Processamento de dados em tempo real: os streams permitem o processamento de dados em tempo real, como vídeo/áudio ao vivo ou grandes conjuntos de dados de APIs.

Tipos de fluxos em Node.js

Existem quatro tipos de streams no Node.js:

  1. Streams legíveis: para leitura de dados.
  2. Streams graváveis: para gravação de dados.
  3. Duplex Streams: Streams que podem ler e gravar dados simultaneamente.
  4. Transform Streams: Um tipo de Duplex Stream onde a saída é uma versão modificada da entrada (por exemplo, compactação de dados).

Vamos examinar cada tipo com exemplos.

1. Fluxos legíveis

Streams legíveis são usados ​​para ler dados pedaço por pedaço. Por exemplo, ao ler um arquivo grande, usar um fluxo legível nos permite ler pequenos pedaços de dados na memória em vez de carregar o arquivo inteiro.

Exemplo: lendo um arquivo usando fluxo legível

const fs = require('fs');

// Create a readable stream
const readableStream = fs.createReadStream('largefile.txt', { encoding: 'utf8' });

// Listen for data events and process chunks
readableStream.on('data', (chunk) => {
  console.log('Chunk received:', chunk);
});

// Listen for the end event when no more data is available
readableStream.on('end', () => {
  console.log('No more data.');
});

// Handle error event
readableStream.on('error', (err) => {
  console.error('Error reading the file:', err);
});

Explicação:

  • fs.createReadStream() cria um fluxo para ler o arquivo em pedaços.
  • O evento de dados é acionado sempre que um pedaço está pronto, e o evento final é acionado quando não há mais dados para ler.

2. Fluxos graváveis

Streams graváveis ​​são usados ​​para gravar dados pedaço por pedaço. Em vez de gravar todos os dados de uma vez, você pode transmiti-los para um arquivo ou outro destino gravável.

Exemplo: Gravando dados usando fluxo gravável

const fs = require('fs');

// Create a writable stream
const writableStream = fs.createWriteStream('output.txt');

// Write chunks to the writable stream
writableStream.write('Hello, World!\n');
writableStream.write('Streaming data...\n');

// End the stream (important to avoid hanging the process)
writableStream.end('Done writing.\n');

// Listen for the finish event
writableStream.on('finish', () => {
  console.log('Data has been written to output.txt');
});

// Handle error event
writableStream.on('error', (err) => {
  console.error('Error writing to the file:', err);
});

Explicação:

  • fs.createWriteStream() cria um fluxo gravável.
  • Os dados são gravados no stream usando o método write().
  • O evento final é acionado quando todos os dados são gravados e o método end() marca o fim do fluxo.

3. Fluxos Duplex

Streams duplex podem ler e gravar dados. Um exemplo típico de fluxo duplex é um soquete de rede, onde você pode enviar e receber dados simultaneamente.

Exemplo: Fluxo Duplex

const { Duplex } = require('stream');

const duplexStream = new Duplex({
  write(chunk, encoding, callback) {
    console.log(`Writing: ${chunk.toString()}`);
    callback();
  },
  read(size) {
    this.push('More data');
    this.push(null);  // End the stream
  }
});

// Write to the duplex stream
duplexStream.write('Hello Duplex!\n');

// Read from the duplex stream
duplexStream.on('data', (chunk) => {
  console.log(`Read: ${chunk}`);
});

Explicação:

  • Definimos um método de gravação para escrita e um método de leitura para leitura.
  • Streams duplex podem lidar com leitura e gravação simultaneamente.

4. Transformar fluxos

Transform streams modificam os dados à medida que passam pelo stream. Por exemplo, um fluxo de transformação pode compactar, criptografar ou manipular dados.

Exemplo: Transform Stream (texto em maiúsculas)

const { Transform } = require('stream');

// Create a transform stream that converts data to uppercase
const transformStream = new Transform({
  transform(chunk, encoding, callback) {
    this.push(chunk.toString().toUpperCase());
    callback();
  }
});

// Pipe input to transform stream and then output the result
process.stdin.pipe(transformStream).pipe(process.stdout);

Explicação:

  • A entrada de dados de stdin é transformada em maiúsculas pelo método transform e depois gerada em stdout.

Fluxos de tubulação

Um dos principais recursos dos streams Node.js é sua capacidade de serem canalizados. A tubulação permite encadear fluxos, passando a saída de um fluxo como entrada para outro.

Exemplo: canalizando um fluxo legível para um fluxo gravável

const fs = require('fs');

// Create a readable stream for the input file
const readableStream = fs.createReadStream('input.txt');

// Create a writable stream for the output file
const writableStream = fs.createWriteStream('output.txt');

// Pipe the readable stream into the writable stream
readableStream.pipe(writableStream);

// Handle errors
readableStream.on('error', (err) => console.error('Read error:', err));
writableStream.on('error', (err) => console.error('Write error:', err));

Explicação:

  • O método pipe() conecta o fluxo legível ao fluxo gravável, enviando blocos de dados diretamente de input.txt para output.txt.

Casos de uso prático de streams Node.js

  1. Ler e gravar arquivos grandes: em vez de ler um arquivo inteiro na memória, os fluxos permitem processar o arquivo em pequenos pedaços.
  2. Processamento de dados em tempo real: Streams são ideais para aplicações em tempo real, como processamento de áudio/vídeo, aplicações de bate-papo ou feeds de dados ao vivo.
  3. Solicitações/respostas HTTP: solicitações e respostas HTTP em Node.js são fluxos, facilitando o processamento de dados recebidos ou o envio progressivo de dados.

Conclusão

Os fluxos

Node.js fornecem uma maneira poderosa e eficiente de lidar com operações de E/S, trabalhando com dados em blocos. Esteja você lendo arquivos grandes, canalizando dados entre fontes ou transformando dados dinamicamente, os streams oferecem uma solução com desempenho e eficiência de memória. Compreender como aproveitar fluxos legíveis, graváveis, duplex e de transformação em seu aplicativo pode melhorar significativamente o desempenho e a escalabilidade do seu aplicativo.

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/imsushant12/understanding-nodejs-streams-what-why-and-how-to-use-them-53da?1 Se houver alguma violação, entre em contato com study_golang@163 .com para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3