Search code examples
javascriptnode.jsbluebirdfs

How to wait before file stream is done writing before I close it?


I create a file stream to write a csv file:

    var logger = fs.createWriteStream('restaurants.csv', {
      flags: 'w' // 'a' means appending (old data will be preserved)
    });
    logger.write("sep=,\n");

When I'm done writing, I close the stream like this:

    logger.end();
    logger.close();

But when I do that, part of the file is missing at the end. I tried to sleep before closing the stream:

    await Promise.delay(2000);
    logger.end();
    logger.close();

And suddenly, the file is complete. But timeout is kinda stupid solution. Does filestream emit any event when it's done writing. Basically what I need is:

    await logger.doneWriting();
    logger.end();
    logger.close();

I can promisify any event of course, but which event it is?


Solution

  • fs.createWriteStream() returns a WriteStream object which is a WritableStream, this means that when you call .write() you're calling writable.write() which actually takes a callback as a parameter so you can close the stream right after it finishes!

    var logger = fs.createWriteStream('restaurants.csv', {
      flags: 'w' // 'a' means appending (old data will be preserved)
    });
    logger.write("sep=,\n", () => {
        // Done writing... do what's needed then close the stream if it isn't used anymore
    });
    

    Asynchronous JavaScript has practically become a standard nowadays, always be on the lookout for a callback function, it's what allows you to run code after the async block finishes when it finishes.