I'm trying to read several files synchronously with fast-csv, it should looks like:
read file 1
execute something while reading
read file 2
execute something while reading (it must be execute after first execution's file that's why I need to do this synchronously)
...
Here is my code simplified:
const csv = require('fast-csv');
const PROCEDURES = [
{ "name": "p1", "file": "p1.csv" },
{ "name": "p2", "file": "p2.csv" },
];
const launchProcedure = (name, file) => {
try {
const fs = require("fs");
const stream = fs.createReadStream(file, {
encoding: 'utf8'
});
console.log('launching parsing...');
stream.once('readable', () => {
// ignore first line
let chunk;
while (null !== (chunk = stream.read(1))) {
if (chunk == '\n') {
break;
}
}
// CSV parsing
const csvStream = csv.fromStream(stream, {
renameHeaders: false,
headers: true,
delimiter: ',',
rowDelimiter: '\n',
quoteHeaders: false,
quoteColumns: false
}).on("data", data => {
console.log('procedure execution...');
// I execute a procedure...
}).on("error", error => {
logger.error(error);
}).on("end", data => {
logger.info(data);
});
});
}
catch (e) {
logger.info(e);
}
}
PROCEDURES.forEach(procedure => {
launchProcedure(procedure.name, procedure.file);
});
Output will be:
launching parsing...
launching parsing...
procedure execution...
procedure execution...
Problem is on stream.once but I used this to ignore first line. I tried to promisify my function and use async await... ( I had a similar problem when executing my procedure and I solved it by using csvStream.pause() and csvStream.resume() ).
Any idea ?
Using promises seems like a good way to solve this. Be aware though, that when you create a new Promise with
new Promise(executor)
, theexecutor
is executed immediately. So you need to delay it until the previous promise has been executed.To "promisify" the
launchProcedure
function, you need to return a new Promise at the start of the function:And then you need to call
resolve
(for success) andreject
(for failure) whenever the parsing has finished.Finally we need to string together the promises:
Note that I use a lambda function within the
then
to delay the creation of the Promise. (By the way, there are also nicer ways to string together promises.)The final code looks like this:
The problem here is that
launchProcedure
has to beasync
in order to useawait
. Another problem is that usingasync
/await
together withArray.forEach
is not the best choice (see here).You can do this using the "for-of" loop and await inside the loop body:
OUTPUT:
Hey I found a solution in the meantime before seiing your answers (sorry for posting later) !