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

289
Vistas
fs.readfile cambia el alcance de la matriz global y no se puede usar fuera de ella

Tengo 2 secciones del código 1) que llama 2nd para completar la matriz y escribirla en un archivo.

 async function timeSeries(obj) { data = [ { original_value: [] } ] //read file named as passed object's _id await fs.readFile("./api/assignment_data/" + obj._id + ".json", "utf-8", function read(err, datas) { if (err) { throw err; } const filedata = JSON.parse(datas) filedata.map(line => data[0].original_value.push(line.original_value)) }) setTimeout(() => { try { fs.writeFileSync("./api/timeseries.json", JSON.stringify(data), { encoding: 'utf8', flag: 'w' }) } catch (error) { console.log(error) } }, 300); }

El problema es que no puedo acceder a la matriz de datos global anterior después de usarla dentro de la función fs.readfile (problema del infierno del alcance de devolución de llamada), tuve que configurar el tiempo de espera y luego puedo escribirlo dentro de un archivo usando otra función fs.writeFileSync (si devuelvo la matriz, recibo una promesa, quiero datos). ¿Cómo resuelvo esto? en lugar de escribirlo en otro archivo y usarlo dentro de otra ruta (a continuación), ¿cómo puedo devolver directamente la matriz en la segunda ruta y pasarla como json res?

sección 2)

 router.route("/api/debug/:num").get((req, res) => { fs.readFile("./api/assignment_data/metrics.json", "utf8", function read(err, data) { if (err) { console.log(err); } const objdata = JSON.parse(data) timeSeries(objdata[req.params.num]) }) fs.readFile("./api/timeseries.json", "utf8", function read(err, data) { if (err) { console.log(err); } const objdata = JSON.parse(data) res.json(data) }) })
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Si usa fs.readFile y desea realizar una acción después de que se haya leído el archivo, debe realizar la acción (escribir y leer un archivo en su caso) dentro de la función de devolución de llamada. Además, puede usar fs.readFileSync si puede leer sincrónicamente.

about 4 years ago · Juan Pablo Isaza Denunciar

0

En primer lugar, tenemos que explicar algunas cosas:

fs.readFile() no bloquea y es asíncrono. Eso significa que cuando lo llama, inicia la operación y luego regresa inmediatamente y comienza a ejecutar el código que viene justo después. Luego, algún tiempo después, llama a su devolución de llamada.

Entonces, tu código es:

  1. Llamando fs.readFile()
  2. Luego, inmediatamente configurando un temporizador
  3. Luego, es una carrera indeterminada entre la devolución de llamada fs.readFile() y el temporizador para ver quién termina primero. Si el temporizador finaliza primero, llamará a su devolución de llamada e intentará acceder a los data ANTES de que se completen (porque la devolución de llamada fs.readFile() aún no se ha llamado).

No puede escribir código confiable de esta manera ya que está adivinando el momento de las operaciones asincrónicas indeterminadas. En su lugar, debe usar el resultado asíncrono desde dentro de la devolución de llamada porque ese es el único lugar en el que conoce el momento en que finalizó y, por lo tanto, cuándo es válido. Entonces, una forma de resolver su problema es encadenar las operaciones asincrónicas para que coloque la segunda DENTRO de la devolución de llamada de la primera:

 function timeSeries(obj, callback) { //read file named as passed object's _id fs.readFile("./api/assignment_data/" + obj._id + ".json", "utf-8", function read(err, datas) { if (err) { console.log(err); // tell caller about our error callback(err) return; } else { let data = [{original_value: []}]; const filedata = JSON.parse(datas); for (let line of filedata) { data[0].original_value.push(line.original_value); } fs.writeFile("./api/timeseries.json", JSON.stringify(data), { encoding: 'utf8' }, (err) => { if (err) { console.log(err); callback(err); return; } else { // give our data to the caller callback(data); } }); } }) }

Luego, para llamar a esta función, le pasa una devolución de llamada y en la devolución de llamada puede ver el error u obtener los datos.


En nodejs modernos, es un poco más fácil usar async/await y las interfaces basadas en promesas en el módulo fs :

 const fsp = require('fs').promises; async function timeSeries(obj) { //read file named as passed object's _id try { let datas = await fsp.readFile("./api/assignment_data/" + obj._id + ".json", "utf-8"); const filedata = JSON.parse(datas); let data = [{original_value: []}]; for (let line of filedata) { data[0].original_value.push(line.original_value); } await fsp.writeFile("./api/timeseries.json", JSON.stringify(data), { encoding: 'utf8' }); return data; } catch(e) { console.log(e); // handle error here or throw back to the caller throw e; } }

Para esta versión, la persona que llama puede usar await y try/catch para obtener errores:

 try { let data = await timeSeries(obj); // do something with data here } catch(e) { // handle error here }
about 4 years ago · Juan Pablo Isaza Denunciar

0

Según el código que haya escrito, podría modificarlo usando async-await simple; espero que esto ayude

 import fs from 'fs' async function timeSeries(obj) { const data = [{ original_value: [] }] const assData = fs.readFileSync('./api/assignment_data/metrics.json', 'utf8') const filedata = JSON.parse(assData) filedata.map(line => data[0].original_value.push(line.original_value)) // no need for timeOut fs.writeFileSync('./api/timeseries.json', JSON.stringify(data)); //return data if u need return data } router.route("/api/debug/:num").get(async (req, res) => { try { const metricData = fs.readFileSync('./api/assignment_data/metrics.json', 'utf8') const objdata = JSON.parse(data) const timeSeriesData = await timeSeries(objdata[req.params.num]) // returning TimeSeriesData res.status(200).json(timeSeriesData) }) } catch (error) { res.status(500).send(error.message) }
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