Praveer Kumar
Praveer Kumar

Reputation: 1018

How do I wait for multiple fs.readFile calls?

My objective is to read data from two files and compare the data. My input files are result3.json and result4.json.The data in these files are coma separated.

result3.json

[
  "temp1.txt",
  "temp2.txt",
]

node:

function readFromFile(file) {
    var fileNames = [];
    //setTimeout(function() {
        fs.readFile(file,function(err, data){
            if (err) {
                return console.log(err);
            }
            var temp = JSON.parse(data.toString().split(","));
            // console.log(temp.length);
            for (let index = 0; index < temp.length; index++) {
                //console.log(temp[index]);
                fileNames.push(temp[index]);
                //console.log(fileNames[index]);
            }
            Done(); // to block the async call
        });
        //},3000);
    //console.log(fileNames.length);
    return fileNames;
}

var baseListOfFiles = readFromFile('./output/result3.json'); // Assume this is the base file
var currentListOfFiles = readFromFile('./output/result4.json'); // Assume this is the current file

function Done(){
    //console.log('Out baseListOfFiles + ' + baseListOfFiles.length);
    for (let index = 0; index < baseListOfFiles.length; index++) {
        console.log("[baseListOfFiles] " + baseListOfFiles[index]);
    }

    //console.log('Out currentListOfFiles+ ' + currentListOfFiles.length);
    for (let index = 0; index < currentListOfFiles.length; index++) {
        console.log("[currentListOfFiles] " + currentListOfFiles[index]);
    }

}

Above is my code. It seems to be async call, so it always return 0 fileNames. Is there any way to control it?

Upvotes: 2

Views: 5331

Answers (2)

user5734311
user5734311

Reputation:

Here's example code using Promises:

const fs = require('fs');

function readFromFile(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, function (err, data) {
            if (err) {
                console.log(err);
                reject(err);
            }
            else {
                resolve(JSON.parse(data));
            }
        });
    });
}

const promises = [
    readFromFile('./output/result3.json'),
    readFromFile('./output/result4.json')
];

Promise.all(promises).then(result => {
    console.log(result);
    baseListOfFiles = result[0];
    currentListOfFiles = result[1];
    // do more stuff
});

First, an array promises is built; each Promise reads the file, then calls resolve with the result.
This array is passed to Promise.all(), which then calls the callback, passing the array of results in the same order.

Upvotes: 10

Geraint
Geraint

Reputation: 3392

You're right, readFile is async. What you're looking for is readFileSync: https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options

With that can can do:

const data = fs.readFileSync(file);

//do something with data

There are a few ways to 'promisify' readFile if you like, the options are discussed here: Using filesystem in node.js with async / await

Upvotes: 2

Related Questions