Michael
Michael

Reputation: 42100

How to create a file stream and write to the stream asynchronously?

I am new to TypeScript/JavaScript and Node.
Now I am trying to create a file stream and write "Hello!" to the stream asynchronously.

#!/usr/bin/env node

import fs from 'fs';

function createStream(filePath: string): Promise<fs.WriteStream> {

  return new Promise<fs.WriteStream>((resolve, reject) => {

    const out = fs.createWriteStream(filePath);

    out.on('close', () => {
      console.log(filePath + ' closed');
      resolve(out);
    });

    out.on('error', (err: any) => {
      console.log(filePath + ' ' + err);
      reject(err);
    });

  });
}

createStream('/tmp/test.txt').then((out:fs.WriteStream) => {
  console.log(out);
  out.write('Hello!');
  out.end();
}) 

This code does create /tmp/test.txt but prints out nothing and the file is empty.
What is the problem with this code ?

Upvotes: 2

Views: 5640

Answers (1)

Patrick Roberts
Patrick Roberts

Reputation: 51946

You don't need to resolve a promise with the fs.WriteStream since its creation is synchronous. Just call fs.createWriteStream() directly and pass the instance to your function to create a promise that settles when the stream closes or errors:

#!/usr/bin/env node

import fs from 'fs';
import stream from 'stream';

function promisify(s: stream.Stream): Promise<void> {
  return new Promise<void>((resolve, reject) => {
    const onClose = () => {
      s.off('error', onError);
      resolve();
    };
    const onError = (error: Error) => {
      s.off('close', onClose);
      reject(error);
    };

    s.once('close', onClose);
    s.once('error', onError);
  });
}

const out = fs.createWriteStream('/tmp/test.txt');

promisify(out).then(() => {
  console.log('Done');
});

out.write('Hello!');
out.end();

Upvotes: 2

Related Questions