Home > Software engineering >  JavaScript logging done before loop is finished
JavaScript logging done before loop is finished

Time:04-05

I want to log some data coming from a CSV file using a for loop for each line. When the for loop is done, I want it to log "done", but it seems like it logs the "done" before the last line of det csv file... CSV File:

CHANNEL,TITLE,TEXT
EzaguesTesting,TITLE TIL SR 1,TEKST TIL SR 1
EzaguesTesting2,TITLE TIL SR 2,TEKST TIL SR 2
EzaguesTesting3,TITLE TIL SR 3,TEKST TIL SR 3
EzaguesTesting4,TITLE TIL SR 4,TEKST TIL SR 4
EzaguesTesting5,TITLE TIL SR 5,TEKST TIL SR 5

The code that should log it:

fs.readdir(dirPath, async function (err, lines) {
    for await (const line of lines) {
        await new Promise(resolve => {
            fs.createReadStream(dirPath   line)
                .pipe(csv())
                .on('data', data => {
                    console.log('SR: '   data.CHANNEL   ' Titel: '   data.TITLE   ' Tekst: '   data.TEXT);
                    resolve(true);
                });
        })
    }
    console.log('done');
})

Everything seems to work fine, other than the fact that it logs "done" one line too early...

enter image description here

CodePudding user response:

You resolve your Promise on 'data'. It means that, as soon as your stream sends you the first chunk, you resolve the Promise with this chunk only.

You need to send the result back .on('end').

const files = await fs.promises.readdir(dirPath);

for (const file of files) {
    await new Promise(resolve => {

        let result 

        fs.createReadStream(dirPath   line)
            .pipe(csv())
            .on('data', data => {
                result = data;
            })
            .on('end', () => resolve(result));
    })
}
console.log('done');

I have made some other changes, like using the Promise version of fs.readdir and also renaming lines to files (you are getting file names, not lines).

  • Related