Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

207
Vistas
Leer y modificar datos secuencialmente en node.js

Estoy tratando de leer y modificar algunos archivos csv. Para un archivo csv, el código que escribí es el siguiente:

 const csv = require('csv-parser'); const fs = require('fs'); const results = []; const resultsFiltered = []; fs.createReadStream('csvTest/2005.csv') .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', () => { // Filter results for (i=0; i<results.length; i++) { if (results[i]['Points:2'] == 0) { resultsFiltered.push([results[i]['Points:0'], results[i]['Points:1'], results[i]['displacement:2']]); } } console.log('results filtered: ', resultsFiltered); });

Esto funciona bien, pero cuando trato de recorrer varios archivos, obtengo resultados extraños. Aquí está el código:

 const csv = require('csv-parser'); const fs = require('fs'); const dataFolder = 'csvTest/'; let results, resultsFiltered, stringified; function filterData(_file) { results = []; resultsFiltered = []; console.log('filtering'); fs.createReadStream(dataFolder + _file) .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', () => { // Filter results for (i=0; i<results.length; i++) { if (results[i]['Points:2'] == 0) { resultsFiltered.push([results[i]['Points:0'], results[i]['Points:1'], results[i]['displacement:2']]); } } console.log('done'); return resultsFiltered; }); } const filesList = fs.readdirSync(dataFolder); function main() { for (i=0; i<filesList.length; i++) { console.log(filterData(filesList[i])); } } main();

Entiendo que podría resolverse con async/await, pero todas las formas en que intenté usarlo no tuvieron éxito. Siempre obtengo en la consola el mismo resultado que el código básico anterior:

 filtering undefined filtering undefined filtering undefined done done done

en lugar de lo deseado

 filtering done resultsFiltered filtering done resultsFiltered filtering done resultsFiltered

¿Cómo se debe usar async/await en este caso?

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

No está definido porque su función no tiene declaración de retorno. La declaración de devolución que usa está en realidad en una función de devolución de llamada si observa más de cerca. Lo que puede hacer es prometer su función y usar async await.

 const csv = require("csv-parser"); const fs = require("fs"); const dataFolder = "csvTest/"; let results, resultsFiltered, stringified; function filterData(_file) { return new Promise(res => { results = []; resultsFiltered = []; console.log("filtering"); fs.createReadStream(dataFolder + _file) .pipe(csv()) .on("data", data => results.push(data)) .on("end", () => { // Filter results for (i = 0; i < results.length; i++) { if (results[i]["Points:2"] == 0) { resultsFiltered.push([ results[i]["Points:0"], results[i]["Points:1"], results[i]["displacement:2"] ]); } } console.log("done"); res(resultsFiltered); }); }); } const filesList = fs.readdirSync(dataFolder); async function main() { for (const file of filesList) { let result = await filterData(file); console.log(result); } } main();

Bueno, esto debería funcionar.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Hay múltiples problemas en este código que pueden generar problemas.

El principal problema lógico es que estos flujos son todos asincrónicos y su código no realiza un seguimiento de cuándo terminan de leerse estos flujos. Sus return resultsFiltered; está dentro de la devolución de llamada .on('end', ...) por lo que no está devolviendo nada de su función filterData() (por lo que no está undefined ), sino que solo está regresando de esa devolución de llamada que no va a ninguna parte.

Por lo tanto, cuando recorre estos flujos, tiene muchos de ellos funcionando a la vez y no tiene idea de cuándo terminaron y no hay forma de obtener todos los datos de ellos.

También tiene problemas con las variables locales no declaradas que harán que sean globales accidentales y puedan entrar en conflicto entre sí.

Para resolver el problema de la lógica principal, este es un lugar útil para introducir una promesa que realizará un seguimiento de cuándo finaliza cada transmisión y le permitirá obtener los datos como el valor resuelto de la promesa o obtener un error como motivo de rechazo:

 function filterData(_file) { const results = []; const resultsFiltered = []; return new Promise((resolve, reject) => { fs.createReadStream(dataFolder + _file) .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', () => { // Filter results for (let i = 0; i < results.length; i++) { if (results[i]['Points:2'] == 0) { resultsFiltered.push([results[i]['Points:0'], results[i]['Points:1'], results[i]['displacement:2']]); } } resolve(resultsFiltered); }).on('error', reject); }); }

Luego, puede usar esa promesa para realizar un seguimiento de las cosas en su ciclo:

 const filesList = fs.readdirSync(dataFolder); async function main() { for (let i = 0; i < filesList.length; i++) { const result = await filterData(filesList[i]); console.log(result); } } main().then(() => { console.log("done"); }).catch(err => { console.log(err); });

Tenga en cuenta que esto tiene varias otras correcciones a su código:

  1. Agrega un controlador de eventos de error en su transmisión que rechaza la promesa y, por lo tanto, le brinda la oportunidad de rastrear y manejar errores. Su código original ignoraba los errores.

  2. Esto agrega declaraciones locales con const o let para todas sus variables, lo cual es absolutamente necesario. Su código no declaraba ninguna variable i utilizada en sus bucles, lo que hará que sean variables implícitas y potencialmente entren en conflicto entre sí.

  3. Esto secuencia las secuencias para que no estén todas en progreso a la vez y le permite mantener sus resultados en orden. El código también se escribiría para ejecutarse en paralelo (si hay suficientes recursos disponibles para hacerlo) recopilando todas las promesas y usando Promise.all() para rastrearlas.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Deberá convertir sus operaciones para devolver una promesa para poder esperar los resultados.

PD: no olvide manejar los errores escuchando el evento de error y rechazando la promesa.

 function filterData(_file) { results = []; resultsFiltered = []; console.log('filtering'); return new Promise((resolve) => { fs.createReadStream(dataFolder + _file) .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', () => { // Filter results for (i = 0; i < results.length; i++) { if (results[i]['Points:2'] == 0) { resultsFiltered.push([ results[i]['Points:0'], results[i]['Points:1'], results[i]['displacement:2'], ]); } } console.log('done'); resolve(resultsFiltered) }); }); } const filesList = fs.readdirSync(dataFolder); async function main() { for (i = 0; i < filesList.length; i++) { console.log(await filterData(filesList[i])); } }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda