How to execute functions synchronously to get the right output

Viewed 135

I am making an application which reads a file and extracts the data line by line. Each line is then stored as an array element and that array is required as the final output.

const fs = require('fs');
const readline = require('readline');

var output_array=[];
const readInterface = readline.createInterface({
    input: fs.createReadStream(inp_file),
    console: false
});
readInterface.on('line', function(line) {
    //code for pushing lines into output_array after doing conditional formatting
}

callback (null, output_array);

With this I am getting an empty array. Though if I use 'setTimeout' then it's working fine

setTimeout(() => {
  callback (null, output_array);
}, 2000);

How can I execute this synchronously without having to use 'setTimeout'?

3 Answers

You cannot execute asynchronous functions synchronously. But readline supports the close event, which is triggered when the inputfile is completely read, so you can call the callback there.

readInterface.on('close', () => {
   callback(null, output_array);
});

Of course you could output the content on the close event, but you could also use a promise like this:

function readFile(fileName) {
  return new Promise((resolve, reject) => {
      const readInterface = readline.createInterface({
        input: fs.createReadStream(fileName).on('error', error => {
          // Failed to create stream so reject.
          reject(error);
        }),
      });
      const output = [];
      readInterface.on('error', error => {
        // Some error occurred on stream so reject.
        reject(error);
      });
      readInterface.on('line', line => {
        output.push(line);
      });
      readInterface.on('close', () => {
        // Resolve the promise with the output.
        resolve(output);
      });
  });
}

readFile(inp_file)
  .then(response => {
    callback(null, response);
  })
  .catch(error => {
    // Take care of any errors.
  });

I removed the console setting when calling createInterface() since it does not seem to be a valid option.

Make your callback from readline's close event handler. That way your callback will happen after all lines are read.

readInterface.on('close', function(line) {
  callback (null, output_array);
}
Related