Apologies for all the code here.
We can consume a Readable stream using an async iterator:
// source: http://2ality.com/2018/04/async-iter-nodejs.htmlasyncfunctionprintAsyncIterable(iterable){forawait(constchunkofiterable){console.log('>>> '+chunk);}}printAsyncIterable(fs.createReadStream('my-file.txt','utf8'));And we can use async generators similarly to how one would use a Transform stream:
/** * Parameter: async iterable of chunks (strings) * Result: async iterable of lines (incl. newlines) */asyncfunction*chunksToLines(chunksAsync){letprevious='';forawait(constchunkofchunksAsync){previous+=chunk;leteolIndex;while((eolIndex=previous.indexOf('\n'))>=0){// line includes the EOLconstline=previous.slice(0,eolIndex+1);yieldline;previous=previous.slice(eolIndex+1);}}if(previous.length>0){yieldprevious;}}/** * Parameter: async iterable of lines * Result: async iterable of numbered lines */asyncfunction*numberLines(linesAsync){letcounter=1;forawait(constlineoflinesAsync){yieldcounter+': '+line;counter++;}}Then, we can "pipe" these together like so:
asyncfunctionmain(){printAsyncIterable(numberLines(chunksToLines(fs.createReadStream('my-file.txt','utf8'))));}main();That's neat, but also kind of hideous. What if we could leverage stream.pipeline() to do something like this?
asyncfunctionmain(){stream.pipeline(fs.createReadStream('my-file.txt','utf8'),chunksToLines,numberLines,printAsyncIterable);}main();I'm unfamiliar with the guts of stream.pipeline()--and completely new to async iterators and generators--so don't know how feasible something like this is.
FWIW, the "hideous nested function calls" can be naively replaced by use of the godlike Array.prototype.reduce():
constpipeline=async(...args)=>args.reduce((acc,arg)=>arg(acc));asyncfunctionmain(){pipeline(fs.createReadStream('my-file.txt','utf8'),chunksToLines,numberLines,printAsyncIterable);}main();Reference: https://twitter.com/b0neskull/status/1115325542566227968
Apologies for all the code here.
We can consume a
Readablestream using an async iterator:And we can use async generators similarly to how one would use a
Transformstream:Then, we can "pipe" these together like so:
That's neat, but also kind of hideous. What if we could leverage
stream.pipeline()to do something like this?I'm unfamiliar with the guts of
stream.pipeline()--and completely new to async iterators and generators--so don't know how feasible something like this is.FWIW, the "hideous nested function calls" can be naively replaced by use of the godlike
Array.prototype.reduce():Reference: https://twitter.com/b0neskull/status/1115325542566227968