0

Using Electron's net module, the aim is to fetch a resource and, once the response is received, to pipe it to a writeable stream like so:

const stream = await fetchResource('someUrl');
stream.pipe(fs.createWriteStream('./someFilepath'));

As simplified implementation of fetchResource is as follows:

import { net } from 'electron';

async function fetchResource(url) {
  return new Promise((resolve, reject) => {
    const data = [];

    const request = net.request(url);
    request.on('response', response => {
      response.on('data', chunk => {
        data.push(chunk);
      });
      response.on('end', () => {
        // Maybe do some other stuff with data...
      });
      // Return the response to then pipe...
      resolve(response);
    });
    request.end();
  });
}

The response ends up being an instance of IncomingMessage, which implements a Readable Stream interface according to the node docs, so it should be able to be piped to a write stream.

The primary issue is there ends up being no data in the stream that get's piped through

IliasT
  • 3,973
  • 1
  • 24
  • 26

1 Answers1

0

Answering my own question, but the issue is reading from multiple sources: the resolved promise and the 'data' event. The event listener source was flushing out all the data before the resolved promise could get to it.

A solution is to fork the stream into a new one that won't compete with the original if more than once source tries to pipe from it.

import stream from 'stream';

// ...make a request and get a response stream, then fork the stream...
const streamToResolve = response.pipe(new stream.PassThrough());

// Listen to events on response and pipe from it
// ...

// Resolve streamToResolve and separately pipe from it
// ...
IliasT
  • 3,973
  • 1
  • 24
  • 26
  • The race conditions mentioned for `PassThrough` on the other [qa](https://stackoverflow.com/a/19561718/1318694) seem like a probability with a file write compared to js code. If you into that you could modify your original function to handle both the pipe/write and data processing inside the promise. – Matt May 24 '19 at 00:59