createWriteStream instance shadowing another instance in nodeJS

38 views Asked by At

My aim is to do something like that :

function writer1(data,file){
    const w = fs.createWriteStream(file,{flags:'w'})
    for(let i = 0; i< data.length; i++){
       w.write(data[i])
    }
    w.end()
}

function writer2(data,file, *some-stuff*){
    const w = fs.createWriteStream(file,{flags:'w'})
    for(let i = 0; i< data.length; i++){
        if(data[i] !== *some-stuff*){
              w.write(data[i])
        }
    }
    w.end()
}

writer1(data,"file.txt")
writer2(data,"file.txt", "some string")

IMPORTANT TO NOTE : in the true piece of code I'm writing, writer1 has a condition to run; it runs only if the file it needs to write does not exists

But here is my problem; if the according files does not exists, i.e. if the 'STATE' of the project is init-state, then writer1 is launched but somehow shadows the execution of writer2. The result is a txt file filled with the content DATA.

On the second pass, then writer1 is not launched, does not shadow the execution of writer2, and the result is a txt file filled with the content of DATA MINUS the variable some-stuff.

Essentially, my question is :

Why is the first stream shadowing the second and how to prevent that ?

I do understand that there's something asynchronous to be dealed with or a request to be made to the stream object in order to allow for other streams to access the same file. What is missing ?

1

There are 1 answers

0
Heiko Theißen On

Writing to a stream is an asynchronous process. If you open the file again in writer2 before writer1 has closed it, the writings of writer2 may be lost.

The following variant of writer1 is an asynchronous function that resolves only after closing the file. You can await this before calling writer2.

function writer1(data, file) {
  return new Promise(function(resolve, reject) {
    const w = fs.createWriteStream(file, {flags: 'w'})
    .on("close", resolve)
    .on("error", reject);
    for (let i = 0; i < data.length; i++)
      w.write(data[i]);
    w.end();
  });
}
function writer2(...) // similar
await writer1(data, "file.txt");
await writer2(data, "file.txt", "some string");

But I second jfriend00's question about what problem you are trying to solve.