Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

119
Visualizações
Hacer ReadableStream secuencial

Uso fetchAPI para recuperar mis datos del backend como una secuencia. Descifro los datos fragmento por fragmento y concateno el contenido nuevamente para el archivo original.

Descubrí que la secuencia parece proporcionar datos de manera diferente cada vez que hace que los fragmentos sean diferentes. ¿Cómo puedo forzar la transmisión a los fragmentos en la secuencia original?

 fetch(myRequest, myInit).then(response => { var tmpResult = new Uint8Array(); const reader = response.body.getReader(); return new ReadableStream({ start(controller) { return pump(); function pump() { return reader.read().then(({ done, value }) => { // When no more data needs to be consumed, close the stream if (value) { //values here are different in order every time //making my concatenated values different every time controller.enqueue(value); var decrypted = cryptor.decrypt(value); var arrayResponse = decrypted.toArrayBuffer(); if (arrayResponse) { tmpResult = arrayBufferConcat(tmpResult, arrayResponse); } } // Enqueue the next data chunk into our target stream if (done) { if (counter == length) { callback(obj); } controller.close(); return; } return pump(); }); } } }) })
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

La documentación nos dice que:

Cada fragmento se lee secuencialmente y se envía a la interfaz de usuario, hasta que la secuencia haya terminado de leerse, momento en el que regresamos de la función recursiva e imprimimos la secuencia completa en otra parte de la interfaz de usuario.

Hice un programa de prueba con node, usando node-fetch :

 import fetch from 'node-fetch'; const testStreamChunkOrder = async () => { return new Promise(async (resolve) => { let response = await fetch('https://jsonplaceholder.typicode.com/todos/'); let stream = response.body; let data = ''; stream.on('readable', () => { let chunk; while (null !== (chunk = stream.read())) { data += chunk; } }) stream.on('end', () => { resolve(JSON.parse(data).splice(0, 5).map((x) => x.title)); }) }); } (async () => { let results = await Promise.all(new Array(10).fill(testStreamChunkOrder())) let joined = results.map((r) => r.join('')); console.log(`Is every result same: ${joined.every((j) => j.localeCompare(joined[0]) === 0)}`) })()

Este obtiene un json aleatorio de lista de tareas pendientes y lo transmite fragmento por fragmento, acumulando los fragmentos en data . Cuando finaliza la transmisión, analizamos el json completo y tomamos los primeros 5 elementos de la lista de tareas y mantenemos solo los títulos, después de lo cual devolvemos el resultado de forma asíncrona.

Todo este proceso se hace 10 veces. Cuando tenemos 10 listas de títulos transmitidas, revisamos cada lista de títulos y unimos los nombres de los títulos para formar una cadena. Finalmente, usamos .every para ver si cada una de las 10 cadenas es la misma, lo que significa que cada json se obtuvo y transmitió en el mismo orden .

Así que creo que el problema está en otra parte: la transmisión en sí está funcionando correctamente. Si bien utilicé node-fetch en lugar de la API Fetch real, creo que es seguro decir que la API Fetch real funciona como debería.

También noté que está llamando directamente a response.body.getReader() , pero cuando miré la documentación , la llamada body.getReader then realiza dentro de otra declaración:

 fetch('./tortoise.png') .then(response => response.body) .then(body => { const reader = body.getReader();

Puede que esto no importe, pero considerando todo lo demás en su código, como el exceso de envoltura y retorno de funciones, creo que sus problemas podrían desaparecer simplemente leyendo un par de tutoriales sobre flujos y limpiando un poco el código. Y si no, aún estará en una mejor posición para averiguar si el problema está en una de sus muchas funciones que no está dispuesto a exponer. El comportamiento del código asincrónico es intrínsecamente difícil de depurar y la falta de información sobre dicho código lo hace aún más difícil.

about 4 years ago · Juan Pablo Isaza Relatório

0

Supongo que está utilizando la familia de métodos de cifrado/descifrado en la biblioteca crypto del nodo. Podemos simplificar esto usando flujos primero canalizando ReadableStream en un TransformStream descifrado (un flujo que es tanto legible como escribible) a través de ReadableStream#pipe() .

 const { createDecipherIv } = require('crypto'); const { createWriteStream } = require('fs'); const { pipeline } = require('stream'); // change these to match your encryption scheme and key retrieval const algo = 'aes-256-cbc'; const key = 'my5up3r53cr3t'; // put your initialization vector you've determined here // leave null if you are not (or the algo doesn't support) using an iv const iv = null; // creates the decipher TransformStream const decipher = createDecipherIv(algo, key, iv); // write plaintext file here const destFile = createWriteStream('/path/to/destination.ext'); fetch(myRequest, myInit) .then(response => response.body) .then(body => body.pipe(decipher).pipe(destFile)) .then(stream => stream.on('end', console.log('done writing file')));

También puede canalizar esto para que se lea en un búfer, canalizar al navegador, etc., solo asegúrese de hacer coincidir su algoritmo, clave e iv donde esté definiendo sus funciones de cifrado/descifrado.

about 4 years ago · Juan Pablo Isaza Relatório

0

Si tomamos en serio el patrón en ese ejemplo de MDN, deberíamos usar el controlador para poner en cola los datos descifrados (no el value aún encriptado) y agregar los resultados con el flujo devuelto por la primera promesa. En otras palabras...

 return fetch(myRequest, myInit) // Retrieve its body as ReadableStream .then(response => { const reader = response.body.getReader(); return new ReadableStream({ start(controller) { return pump(); function pump() { return reader.read().then(({ done, value }) => { // When no more data needs to be consumed, close the stream if (done) { controller.close(); return; } // do the computational work on each chunk here and enqueue // *the result of that work* on the controller stream... const decrypted = cryptor.decrypt(value); controller.enqueue(decrypted); return pump(); }); } } }) }) // Create a new response out of the stream .then(stream => new Response(stream)) // Create an object URL for the response .then(response => response.blob()) .then(blob => { const arrayResponse = blob.toArrayBuffer(); // arrayResponse is the properly sequenced result // if the caller wants a promise to resolve to this, just return it return arrayResponse; // OR... the OP code makes reference to a callback. if that's real, // call the callback with this result // callback(arrayResponse); }) .catch(err => console.error(err));
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda