Home > database >  JavaScript function doesn't wait for file system operations
JavaScript function doesn't wait for file system operations

Time:09-15

I'm trying to create a simple JS function which reads the directory, loop over all the files inside that DIR and push information in the array. So console.logs regarding file data do output the correct data, but console.log({response}) at the end of the newFunc function doesn't output anything neither does the getFileData from awaited async function. However I've also tried to put timeout on the called async function which results in the correct returned response (this means JS doesn't wait for my file read to finish it's work).

Functionality meantioned above:

const newFunc = async () => {
  let response: any = [];
  fs.readdir("files", function (err, files) {
    if (err) {
      console.error("Could not list the directory.", err);
      process.exit(1);
    }

    for (const file of files) {
      fs.stat(`files/${file}`, (err, stats) => {
        if (err) {
          throw err;
        }

        // print file information
        console.log(`File Data Last Modified: ${stats.mtime}`);
        console.log(`File Status Last Modified: ${stats.ctime}`);
        console.log(`File Status Last Modified: ${stats.size}`);
        console.log({ file });
        response.push({
          fileName: file,
          updatedAt: stats.mtime,
          createdAt: stats.ctime,
          size: stats.size,
        });
      });
    }
  });
  console.log({ response });

  return response;
};

NodeJS endpoint functionality:

  const getFileData = await newFunc();
  console.log({getFileData})
  res.status(200).json(getFileData);

CodePudding user response:

You should use readdirSync and statSync functions. This way the code will wait for the response from the function calls. Currently, due to async nature of fs.readdir and fs.stat methods the code doesn't wait and logs empty response array while also returning an empty response.

Your newFunc method should look like this:

const newFunc = async () => {
  let response: any = [];
  try {
    const files = fs.readdirSync('files');
    for (const file of files) {
      const stats = fs.statSync(`files/${file}`);
      console.log(`File Data Last Modified: ${stats.mtime}`);
      console.log(`File Status Last Modified: ${stats.ctime}`);
      console.log(`File Status Last Modified: ${stats.size}`);
      console.log({ file });
      response.push({
        fileName: file,
        updatedAt: stats.mtime,
        createdAt: stats.ctime,
        size: stats.size,
      });
    }
  }
  catch(err) {
    console.log(err);
    throw err;
  }
  return response;
}

CodePudding user response:

readdir and stat are async operations so it seems that in newFunc you are returning the value of response not waiting for these async operations to complete. So, you could use readdirSync and statSync instead of readdir and stat or you could probably just add an await in your current implementation in front of the fs.readdir and fs.stat calls.

  • Related