Soy nuevo en el paradigma impulsado por eventos javascript / node.js.
Necesito detener for after forEach para asegurarme de que se hayan leído todos los archivos y luego continúo. ¿Cómo debo implementar wait_for_all_files_read()
en este contexto?
my_list.forEach(function(element) {
fs.readFile(element.file_path, function(err, data) {
if(err) throw err;
element.obj=JSON.parse(data);
});
});
wait_for_all_files_read(); <-----------
analyze(my_list)
Ninguna solución [1] o [2] funciona para mí.
2 respuestas
Cómo haría eso:
- Promisify fs.readFile (usando, por ejemplo, Bluebird)
- Marque la función como asincrónica
- Haga una lista de devoluciones de llamada (my_list.map en lugar de forEach)
- "espera Promise.all (myListOfCallbacks)"
- La siguiente línea después de await se ejecutará una vez finalizadas todas las operaciones
Algo como eso:
const {promisisfy} = require('util')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const fileNames = getFilenamesArray();
async function executeMe() {
try {
const arrayWithFilesContent = await Promise.all(
fileNames.map(name => readFile(name))
);
return analyze(arrayWithFilesContent);
}
catch (err) {
handleError(err)
}
}
executeMe();
Puedo sugerirle que reescriba el código para prometer: será mucho más fácil lidiar con él
const {promisisfy} = require('util')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const fileNames = getFilenamesSomehow() // <-- returns array with path, e.g. ["./package.json", "/etc/hosts", "/etc/passwd"]
Promise.all(fileNames.map(name => readFile(name)))
.then(arrayWithFilesContent => analyze(arrayWithFilesContent))
.catch(err => handleError(err))
Siguiente paso lo que puede hacer: mover el código a funciones asíncronas / en espera
UPD
Suponga que necesita leer solo un archivo, luego analice los datos a json y analice el resultado de alguna manera.
En este caso puedes hacer lo siguiente:
readFile(singleFileName)
.then(function (singleFileContent) {
return JSON.parse(singleFileContent)
})
.then(function (singleFileContentInJson) {
return analyze(singleFileContentInJson)
})
.catch(funciton (error) {
//here you can process all errors from functions above: reading file error, JSON.parse error, analyze error...
console.log(error)
})
Entonces suponga que necesita analizar un montón de archivos
const fileNames = [...] // array with file names
// this create an array of promises, each of them read one file and returns the file content in JSON
const promises = fileNames.map(function (singleFileName) {
return readFile(singleFileName)
.then(function (singleFileContent) {
return JSON.parse(singleFileContent)
})
})
// promise all resolves (calls callback in 'then') all of promises in array are resolved and pass to then callback array with result of each promise
Promise.all(promises)
.then(function (arrayWithResults) {
return analyze(arrayWithResults)
})
// catch callback calls if one of promises in array rejects with error from the promise - so you can handle e.g. read file error or json parsing error here
.catch(function (error) {
//here you can handle any error
console.log(error)
})
Intente buscar en Google algún artículo para leer cómo funcionan las promesas. P.ej. puede comenzar desde el artículo mdn
Preguntas relacionadas
Preguntas vinculadas
Nuevas preguntas
javascript
Para preguntas sobre la programación en ECMAScript (JavaScript / JS) y sus diversos dialectos / implementaciones (excepto ActionScript). Incluya todas las etiquetas relevantes en su pregunta; por ejemplo, [node.js], [jquery], [json], etc.