Hands-on: Streams - Parte 1

Escrito por

Olá!

Neste post, vamos falar sobre Streams, um conceito utilizando em JavaScript mas que pode ser aplicado em outras linguagens. Nele temos uma grande quantidade de conteúdo para explorar.

O que é um Stream?

É um Fluxo de dados. Quando queremos ler um arquivo muito grande, por exemplo, ele permite que façamos um fluxo de dados na leitura deste arquivo.

Qual a vantagem de existir este fluxo de dados?

Primeiramente isso permite lermos arquivos gigantescos e transformar os dados na medida que vamos lendo estes dados.

Outra coisa interessante sobre o Stream é que podemos fazer o Pipe (uma ligação) de um Stream com outro, como por exemplo um Stream de leitura com um Stream de escrita integrando os dois de forma fluída. Isso é muito bom para trabalharmos com movimento de dados, tratando pedaços deste arquivo à medida que eu vou lendo, sem precisar colocar ele todo na memória.

No JavaScript, temos quatro tipos de Stream: Readable (leitura), Writable (escrita), Duplex(ambos os anteriores juntos) e Transform (permite transformação de dados).

Readable

Primeiro vamos pegar um arquivo grande, por exemplo arquivo.txt e vamos ler ele com Stream. Vamos chamar o fs para ter acesso a isso.

Uma curiosidade: o Stream no Node é implementável, ou seja, quando algum módulo implementa o Stream, podemos tratá-lo da mesma forma, podendo utilizar os mesmos métodos em outros Streams.

1const fs = require("fs")
2const readable = sf.crateReadStream("arquivo.txt")

Nós temos dois tipos de readable Stream: o paused mode, onde ele para e eu solicito os dados, e o flowing mode, em que a medida que ele consegue ler os arquivos já vai devolvendo os dados.

Para fazermos o Flowing mode, vamos criar uma arrow function data passando o data para dentro. Lembrando que o data é um buffer, então precisamos adicionar um toString para sabermos o que tem dentro dele.

1const fs = require("fs")
2const readable = sf.crateReadStream("arquivo.txt")
3readable.on("data", data => {
4 console.log(data.toString())
5})

Quando colocamos o readable.on, ele 'ouve' o tipo data e o readable entra em modo flowing, também conhecido como modo push. Este modo é muito utilizado em operações de rede, como por exemplo ler um upload de um arquivo de um usuário (javaScritp client side), com isso vamos tratando estes dados na medida que vai sendo enviado.

Podemos criar, também, uma forma em que o readable nos envie a leitura de tempo em tempo usando readable.pause e readable.resume, da seguinte forma:

1const fs = require("fs")
2const readable = sf.crateReadStream("arquivo.txt")
3readable.on("data", data => {
4 console.log(data.toString())
5 readable.pause()
6 setTimeout(() => readable.resume(), 2000)
7})

No exemplo acima, o readable nos retorna partes do arquivo a cada 2 segundos. A segunda forma que podemos fazer é usando o paused mode. Quando o arquivo tiver um evento readable (consegue ler dados do Stream), eu solicito o envio desses dados ao invés dele me enviar de tempo em tempo. Fazemos isso usando o chunk.

1const fs = require("fs")
2const readable = sf.crateReadStream("arquivo.txt")
3readable.on("readable", () => {
4 while ((chunk = readable.read())) {
5 console.log(chunk.toString())
6 }
7})

Qual a vantagem do modo paused?

Eu posso ir processando uma pequena quantia de dados de acordo com o que eu quero.

Conclusão

Essa foi uma noção inicial dos readable Streams, vamos passar por todos os outros modos, mas dentro do readable temos os 2 modos, o pause e o flowing.   Confira o hands-on completo no vídeo:

Curta o DevPleno no Facebook, inscreva-se no canal e não se esqueça de cadastrar seu e-mail para não perder as novidades. Ah, fique à vontade para deixar suas dúvidas e sugestões nos comentários. Abraço!

Evolua mais rápido

Junte-se a milhares de desenvolvedores no nosso time de alunos premium e alcance mais rápido o próximo nível da sua carreira.

Ver cursos Premium