Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

287
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!