Using generators with streams

Everything that we have seen up to this point showcases how we can utilize all of the built-in systems in Node.js to create streaming applications. However, for those that have been following sequentially in the book, we have discussed generators. Those that have been keen to think about them would notice a strong correlation between streams and generators. This is actually the case! We can utilize generators to hook into the Streaming API.

With this concept, we could build generators that can both work in the browser and inside of Node.js without that much overhead. We have even seen in a Chapter 6Message Passing – Learning about the Different Types,how we can get at the underlying stream for the Fetch API. Now, we can write a generator that can work with both of these subsystems.

For now, let's just look at an example of an async generator and how we can hook them into the Node.js streaming system. The example will be to see how we can have a generator as the input for a Readable stream:

  1. We are going to set up a Readable stream to read out the 26 lowercase characters of the English alphabet. We can do this fairly easily by writing the following generator:
function* handleData() {
let _char = 97;
while(_char < 123 ) { //char code of 'z'
yield String.fromCharCode(_char++);
}
}
  1. While the character code is below 123, we keep sending data. We can then wrap this in a Readable stream, like so:
const readable = Readable.from(handleData());
readable.on('data', (chunk) => {
console.log(chunk);
});

If we now run this code, we will see the characters a through z appear in our console. The Readable stream knows that it is the end because a generator produces an object with two keys. The value field gives us the value from the yield expression and the done tells us if the generator has finished running.

This lets the readable interface know when to send out data events (through us yielding a value) and when to close the stream (through the done key being set to true). We could also pipe the output of our readable system into that of the writable to chain the process. This can easily be seen with the following code:

(async() => {
const readable2 = Readable.from(grabData());
const tempFile = createWriteStream('./temp.txt');
readable2.pipe(tempFile);
await once(tempFile, 'finish');
console.log('all done');
})();
Implementing streams through generators and async/await may seem like a good idea, but we should only utilize this if we are trying to put an already async/await piece of code with a stream. Always try to go for readability; utilizing the generator or async/await method will most likely lead to something unreadable.

With the previous example, we have combined the readable from a generator and we have utilized the piping mechanism to send it to a file. With async/await and generators becoming constructs in the JavaScript language, it won't be long before we have streaming as a first-class concept.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.103.77