Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using promises with streams in node.js

Tags:

I've refactored a simple utility to use promises. It fetches a pdf from the web and saves it to disk. It should then open the file in a pdf viewer once saved to disk. The file appears on disk and is valid, the shell command opens the OSX Preview application, but a dialog pops up complaining that the file is empty.

What's the best way to execute the shell function once the filestream has been written to disk?

// download a pdf and save to disk // open pdf in osx preview for example download_pdf()   .then(function(path) {     shell.exec('open ' + path).code !== 0);   });  function download_pdf() {   const path = '/local/some.pdf';   const url = 'http://somewebsite/some.pdf';   const stream = request(url);   const write = stream.pipe(fs.createWriteStream(path))   return streamToPromise(stream); }  function streamToPromise(stream) {   return new Promise(function(resolve, reject) {     // resolve with location of saved file     stream.on("end", resolve(stream.dests[0].path));     stream.on("error", reject);   }) } 
like image 616
2652763 Avatar asked May 16 '17 23:05

2652763


People also ask

Can I use Promise in node JS?

Promises can be used to execute a series of asynchronous tasks in sequential order. Chaining multiple then() methods to a single Promise outcome helps avoid the need to code complicated nested functions (which can result in callback hell).

How do I use node JS streams?

Readable − Stream which is used for read operation. Writable − Stream which is used for write operation. Duplex − Stream which can be used for both read and write operation. Transform − A type of duplex stream where the output is computed based on input.

How many promises can node js handle?

Assuming we have the processing power and that our promises can run in parallel, there is a hard limit of just over 2 million promises. If we dig into the code of V8, the JavaScript engine underlying Chrome and Node.

Are promises executed asynchronously?

A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.


1 Answers

In this line

stream.on("end", resolve(stream.dests[0].path)); 

you are executing resolve immediately, and the result of calling resolve (which will be undefined, because that's what resolve returns) is used as the argument to stream.on - not what you want at all, right.

.on's second argument needs to be a function, rather than the result of calling a function

Therefore, the code needs to be

stream.on("end", () => resolve(stream.dests[0].path)); 

or, if you're old school:

stream.on("end", function () { resolve(stream.dests[0].path); }); 

another old school way would be something like

stream.on("end", resolve.bind(null, stream.dests[0].path));

No, don't do that :p see comments

like image 82
Jaromanda X Avatar answered Sep 30 '22 20:09

Jaromanda X