4

I am trying to build a script which read and write some files. The functions are working fine but I am having trouble making the read/write functions asynchronously. The main problem I have is that I am trying to write a file and then I am trying to import it. For example: given these two functions, the first one is writing to ./myFile.js and the second function is trying to import the file like this:

var fs = require('fs');
const myFile = require('./myFile')

async function writeMyFile() {
    return new Promise((resolve, reject) => {
        fs.promises.readFile('./myFile.js', 'utf8').then((file) => {

        const replacedData = file + 'newLine'

            fs.promises
                .writeFile('./myFile.js', replacedData)
                .then(() => resolve('Writted'))
                .catch(() => reject('Error'));
        });
    });
}

function importMyFile() {
    console.log(myFile) // this is always empty
}

await writeMyFile()
importMyFile()

The thing is that I can see myFile is being written correctly, but I cannot see it in the importMyFile function. When I try these functions separately it works (executing the first one and then the second one)

I tried the following:

  • Using the promise functions from fs library: fs.promises.readFile() and fs.promises.writeFile() (example above)
  • Returning a Promise which resolves when writeMyFile ends. (example above)
  • Importing the file directly in the readMyFile function like this:
function importMyFile() {
    const myFile = require('./myFile')
    console.log(myFile) // this is always empty
}
  • Without returning new Promise like this:
async function writeMyFile() {
    const file = await fs.promises.readFile('./myFile.js', 'utf8')

    const replacedData = file + 'newLine'

    await fs.promises.writeFile('./myFile.js', replacedData)
}

I also see that in the console, the order of the logs are these:

'Writted'
{} //empty file

Keep in mind that this is a simplified version of my case.

EDIT the file I am trying to write and import looks like this ALWAYS:

module.exports = []

And the it is populated, it looks like this:

const myModule = {
    name: 'name',
    surname: 'surname'
}

module.exports = [myModule]

I hope someone knows what is going on here. Thanks!

6
  • 1
    you don't need async AND a promise. async makes the promise for you, so the await finishes after promise is made, but before the write is complete Commented Dec 16, 2021 at 18:15
  • I already tried without returning a Promise -> await fs.promises.readFile(...) and await fs.promises.writeFile(..) but nothing changes Commented Dec 16, 2021 at 18:20
  • I also don't know that require returns anything useful. And, does the file already exist? Why read it before writing it? If it doesn't exist it won't get written Commented Dec 16, 2021 at 18:24
  • The file always exists. I will clarify my code sample. Commented Dec 16, 2021 at 18:27
  • require returns module.exports. if you don't have any exports in myFile.js, it will return an empty object. Commented Dec 16, 2021 at 18:34

2 Answers 2

4

Using require is different than readFile. Using require loads the .js file as a module and brings in its exported elements for use in your code. If you're just interested in printing out the text inside of the .js file, then use fs.readFileSync to do so (you don't need promises if you use the synchronous version of the call).

The code you have will add the string "newLine" to the end of the file, but if your intent was to add an actual newline it should be adding "\n" instead.

A simpler version of your code might look like this:

function writeMyFile() {
  const file = fs.readFileSync('./myFile.js', 'utf8');
  const replacedData = file + '\n';
  fs.writeFileSync('./myFile.js', replacedData);
  return 'Written';
}

function importMyFile() {
  // actually read the file instead of using require()
  const file = fs.readFileSync('./myFile.js', 'utf8');
  console.log(file);
}

writeMyFile()
importMyFile()

Since no asynchronous calls are made, there's no need for promises or awaiting.

If you did intend to use the .js code inside, and it's important to use require then note that once you load it that way into memory, it does not get refreshed after the file on disk changes. Even if you call require a subsequent time it will be smart and say "oh, I already have that one in memory" and not reload it. So delay calling require('./myFile') until after any necessary changes are made and put the require statement inside of importMyFile().

Sign up to request clarification or add additional context in comments.

1 Comment

There we go.. You got it :) I was importing './myFile' more than once in my script. So even if I imported it inside the function it was loading it from the memory. Thank You very much :)
1
await writeMyFile()
importMyFile()

Has to be inside an async function.

For example, calling them like this, and this should work.


(async ()=>{

await writeMyFile()
importMyFile()

})()

Also the output, {} means that there is no module exported from myfile.js.

Edit: The "myFile" variable is containing old data. As it was imported at the beginning of execution. The importMyFile should re import myfile.js.


function importMyFile() {
    myFile = require('./myFile')
    console.log(myFile)  
}

After this the new changes by the writeMyFile will be shown in the console, if the function changed myfile.js's export.

1 Comment

They are in an async function already.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.