Los Streams están disponibles en la API central de Node.js como objetos que permiten que los datos se lean o escriban de forma continua. Básicamente, una secuencia hace eso en trozos en comparación con el búfer que hace su bit a bit, por lo que es un proceso lento.
En programación, el concepto de `pipe` no es nuevo. Los sistemas basados en Unix han estado usándolo pragmáticamente desde la década de 1970. ¿Qué hace una tubería? Una `pipe` generalmente conecta la fuente y el destino. Pasa la salida de una función como la entrada de otra función.
En Node.js, la `pipe` se usa de la misma manera, para emparejar entradas y salidas de diferentes operaciones. `pipe()` está disponible como una función que toma un flujo de origen legible y adjunta la salida a un flujo de destino. La sintaxis general se puede representar como:
```javascript
src.pipe(dest);
```
Múltiples funciones `pipe()` también pueden ser encadenadas juntas.
Este es el tipo de flujo al que puede `pipe()` los datos desde una fuente legible. Para crear un flujo de escritura, tenemos un enfoque de constructor. Creamos un objeto a partir de él y pasamos una serie de opciones. El método toma tres argumentos:
* chunk: un buffer
* codificación: para convertir datos a un formato legible por humanos
* devolución de llamada: una función que se llama cuando los datos se procesan desde el fragmento
```javascript
const { Writable } = require('stream');
const writable = new Writable({
write(chunk, encoding, callback) {
console.log(chunk.toString());
callback();
}
});
process.stdin.pipe(writable);
```
### Streams Duplex
Los flujos dúplex nos ayudan a implementar flujos legibles y grabables al mismo tiempo.
El flujo `stdin` canaliza los datos legibles en el flujo dúplex. El `stdout` nos ayuda a ver los datos. Las partes legibles y grabables de un flujo dúplex operan completamente independientes entre sí.
### Corriente de transformación
Este tipo de flujo es más una versión avanzada del flujo dúplex.
Los datos que estamos consumiendo son los mismos que en el ejemplo anterior de la transmisión dúplex. Lo que hay que notar aquí es que `transform()` no requiere la implementación de métodos de `read` o `write` . Combina ambos métodos en sí.
### ¿Por qué usar Streams?
Dado que Node.js es asíncrono, interactúa pasando devoluciones de llamada a funciones con disco y red. Un ejemplo dado a continuación lee los datos de un archivo en el disco y los responde a través de la solicitud de red del cliente.
```javascript
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
fs.readFile('data.txt', (err, data) => {
res.end(data);
});
});
server.listen(8000);
```
El fragmento de código anterior funcionará, pero todos los datos del archivo irán primero a la memoria para cada solicitud antes de volver a escribir el resultado en la solicitud del cliente. Si el archivo que estamos leyendo es demasiado grande, esto puede convertirse en una llamada de servidor muy pesada y costosa, ya que consumirá una gran cantidad de memoria para que el proceso avance. La experiencia del usuario en el lado del cliente también sufrirá demora.
En este caso, si utilizamos secuencias, los datos se enviarán a la solicitud del cliente como una parte a la vez, tan pronto como se reciban del disco.
```javascript
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
const stream = fs.createReadStream('data.txt');
stream.pipe(res);
});
server.listen(8000);
```
El `pipe()` aquí se ocupa de la escritura o, en nuestro caso, el envío de los datos con el objeto de respuesta y una vez que se leen todos los datos del archivo, para cerrar la conexión.
Nota: `process.stdin` y `process.stdout` se crean en secuencias en el objeto de `process` global proporcionado por la API Node.js.