0

I created multiples functions under a directory called data and fill them with some random data returned by a function called generatedRandomData. To create multiple files I wrote these functions:

const createFile = (fileName, data) => {
  if (fs.existsSync(fileName)) throw new Error('Filename already exists');
  fs.writeFile(fileName, data, {
    encoding: 'utf8',
    flag: 'w',
  }, (error) => {
    if (error) return error;
    console.log('File created successfully');
    return null;
  });
};

const createFiles = (dirPath, sizeList) => {
  if (sizeList && !sizeList.length) throw new Error('The list of size should not be empty');

  const fileCreationPromises = sizeList.map(async (size) => {
    const data = generateRandomData(size);
    const fileName = resolve(dirPath, `./data_${size}.txt`);
    await createFile(fileName, data);
  });
  return Promise.all(fileCreationPromises);
};

Then I call the function generateData in order to generate random data and call the functions described above then create the files:

const generateData = async (dirPath, sizeList) => {
  if (!dirPath) throw new Error('No directory path was provied');
  if (!sizeList || (sizeList && !sizeList.length)) throw new Error('Size list should not be empty');
  await createFiles(dirPath, sizeList);
};

I call another function called execute which reads data from those file in order to continue the treatment:

const execute = async (func, dirPath, label) => {
  const files = fs.readdirSync(dirPath);
  const result = [];
  if (files && files.length) {
    for (const file of files) {
      const filename = resolve(dirPath, `./${file}`);
      const parsedData = readDataFromFile(filename);
      const data = parsedData.split(',').map((d) => Number(d));
      const { length } = data;

      result.push({
        label: length,
        value: getExecutionTime(func, data),
      });
    }
  }
  await createFile(resolve(dirPath, `./${label}`), result);
};

Finally, I call the function initialize:

const { resolve } = require('path');
const fs = require('fs');
const { generateData, sizeList, execute } = require('../utils/helpers');
const { underscorePartial } = require('../main/partial');

const dirPath = resolve(__dirname, '../data');

const initialize = () => {
  if (!fs.existsSync(dirPath)) {
    fs.mkdir(dirPath, async (error) => {
      if (error) throw error;
      await generateData(dirPath, sizeList);
      await execute(underscorePartial, dirPath, 'uExecutionTime.txt');
    });
  }
};

try {
  initialize();
} catch (error) {
  console.log(error);
}

However I realized that uExecutionTime.txt to be created in the final step contains undefined due to the function readDataFromFile which returns undefined. I guess the readDataFromFile starts reading from files before the creation of data finished.Any suggestions to fix my code or are there anything missed or wrong in the code?

Slim
  • 5,527
  • 13
  • 45
  • 81

1 Answers1

2

The problem is your createFile function. You care awaiting it while it doesn't return promise. It is a callback style. It should be wrapped in promise.

const createFile = (fileName, data) => {
  if (fs.existsSync(fileName)) throw new Error('Filename already exists');
  return new Promise((resolve, reject) => {
    fs.writeFile(fileName, data, {
    encoding: 'utf8',
    flag: 'w',
  }, (error) => {
    if (error) reject(error);
    console.log('File created successfully');
    resolve(null);
    });
  });
};

Hope this resolves the issue.

Ashish Modi
  • 7,529
  • 2
  • 20
  • 35
  • 1
    Agree, the createFile function needs to be promisified. @Slim In case you would like to use async/await rather than `new Promise`, please check out this answer. https://stackoverflow.com/a/45463672/3563737 – Wasbeer Jan 26 '20 at 14:44