Reputation: 2673
I have the following code :
var fs = require("fs");
function getMediaList(){
var media_copy_list, line_list;
media_copy_list = [];
fs.readFile("input.csv", function(err, data) {
line_list = data.toString('utf-8').trim().split('\n');
return line_list.forEach(function(file_line) {
var output_path, source_path, split_list;
if (file_line.length) {
split_list = file_line.split(';');
console.log(split_list[0]);
if (split_list.length >= 2) {
source_path = split_list[0].toString('utf-8').trim();
output_path = split_list[1].toString('utf-8').trim();
media_copy_list.push({
source: source_path,
destination: output_path
});
}
}
});
});
}
You can see that that I'm filling a list with :
media_copy_list.push({
source: source_path,
destination: output_path
});
What I'd like to do is to return this list once I have finished reading the input.csv
file.
I don't have any issues if I read the file synchrnously( just have to call return media_copy_list
). But in this case , I don't know.
I heard about async.parallel
but really don't know how to apply.
Example of input.csv
:
FirstPart;SecondPart
Test/test2;Whatever/example
Upvotes: 1
Views: 1225
Reputation: 1591
As noted in the comments, you don't want to return the list from the function.. what you should do is include a callback as a parameter to getMediaList and call that callback with your results. I would use async.each for looping through the lines in the file. You can read more about async.each here: https://github.com/caolan/async#each. Here is an example:
var fs = require("fs");
function getMediaList(callback){
var media_copy_list, line_list;
media_copy_list = [];
fs.readFile("input.csv", function(err, data) {
if(err) {
return callback(err);
}
line_list = data.toString('utf-8').trim().split('\n');
async.each(line_list, function(file_line, next) {
var output_path, source_path, split_list;
if (file_line.length) {
split_list = file_line.split(';');
console.log(split_list[0]);
if (split_list.length >= 2) {
source_path = split_list[0].toString('utf-8').trim();
output_path = split_list[1].toString('utf-8').trim();
media_copy_list.push({
source: source_path,
destination: output_path
});
}
}
next(err);
}, function (err) {
callback(err, media_copy_list);
}
});
}
Upvotes: 1
Reputation: 53576
Just wrap your code inside a promise and resolve it only once you're done. Some suggest callbacks, which does pretty much the same thing, but this pattern is discouraged, now. You should really use a promise.
var fs = require("fs");
function getMediaList(file){
return new Promise(function (resolve, reject) {
fs.readFile(file, 'utf-8', function(err, data) {
if (err) {
return reject(err);
}
resolve(data.split('\n').reduce(function(media_copy_list, file_line) {
var output_path;
var source_path;
var split_list;
file_line = file_line.trim();
if (file_line.length) {
split_list = file_line.split(';');
console.log(split_list[0]);
if (split_list.length >= 2) {
source_path = split_list[0].toString('utf-8').trim();
output_path = split_list[1].toString('utf-8').trim();
media_copy_list.push({
source: source_path,
destination: output_path
});
}
}
return media_copy_list;
}, []));
});
});
}
Then, invoke with
getMediaList('input.csv').then(function (mediaList) {
// ...
}).catch(function (err) {
console.error(err.stack);
});
Note: bluebird, Q, etc. are quite unnecessary since Node 4.2+. Unless you are using an earlier version of Node, try to avoid them. IMO.
The reason why Promise
s are encouraged is because Node will implement async/await, which will allow you to call this exact same function like :
var mediaList = await getMediaList('input.csv');
Upvotes: 1
Reputation: 87
Or you can use promises(bluebird in the case below).
var Promise = require('bluebird'),
fs = require("fs"),
media_copy_list, line_list,
media_copy_list = [];
fs.readFile("input.csv", function(err, data) {
line_list = data.toString('utf-8').trim().split('\n');
Promise.map(line_list, function(file_line) {
var output_path, source_path, split_list;
if (file_line.length) {
split_list = file_line.split(';');
if (split_list.length >= 2) {
source_path = split_list[0].toString('utf-8').trim();
output_path = split_list[1].toString('utf-8').trim();
media_copy_list = {
source: source_path,
destination: output_path
};
}
}
return media_copy_list
}).then(function(values){
console.log(values);
})
});
Upvotes: 0