Consumindo uma stream completa
Em alguns casos é necessário ler a stream de leitura por completa para então poder utilizá-la. Então para isso, deveram ser utilizados os buffers para armazenar temporariamente os dados que estão sendo recebidos pela stream até o fim dela.
import http from 'node:http'
const server = http.createServer(async (request, response) => {
const buffers = []
for await (const chunk of request) {
buffers.push(chunk)
}
const fullStreamContent = Buffer.concat(buffers).toString()
console.log(fullStreamContent)
return response.end(fullStreamContent)
})
server.listen(3001)
Nota
A instrução await no
for
é bem peculiar e é utilizada em situações onde é necessário aguardar que cada interação do loop seja executada para então partir para o próximo loop. No exemplo acima, cada chunk é aguardado ser lido por completo para então passar para o próximo chunk.
O código abaixo simula o envio de dados em larga escala para o servidor criado acima.
import { Readable } from 'node:stream'
class OneToHundredStream extends Readable {
index = 1
_read() {
const i = this.index++
setTimeout(() => {
if (i > 5) {
this.push(null)
} else {
const buf = Buffer.from(String(i))
this.push(buf)
}
}, 1_000)
}
}
fetch('http://localhost:3001', {
method: 'POST',
body: new OneToHundredStream(),
duplex: 'half'
}).then(response => {
return response.text()
}).then(data => {
console.log(data)
})
Para subir o servidor e então executar o arquivo que simula o envio dos dados, execute os seguintes comandos:
$ node src/consumindo-streams/stream-http-server.js
$ node src/consumindo-streams/fake-upload-to-http-stream.js
Como saída nos logs do servidor, teremos:
12345