Reputation: 6140
I am new to the javascript/node.js event driven paradigm.
I need to stop the for after forEach to make sure all files have been read and then I continue. How should I implement wait_for_all_files_read()
in this context?
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)
Neither solution [1] or [2] work for me.
Upvotes: 2
Views: 3485
Reputation: 1546
I can suggest you to rewrite the code to promise - it will make much easy to deal with it
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))
Next step what you may do - move the code to async/await functions
UPD
Assume you need read only one file, then parse it data to json and analyze the result somehow.
It this case you can do next:
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)
})
Then assume you need to analyze bunch of files
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)
})
Try to google some article to read how does promises work. E. g. you can start form mdn article
Upvotes: 4
Reputation: 4811
How I would do that:
Something like that:
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();
Upvotes: 1