Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript (ES6) iterable stream

Is there a pattern for making a stream iterable using ES6 generators?

See 'MakeStreamIterable' below.

import {createReadStream} from 'fs'

let fileName = 'largeFile.txt'
let readStream = createReadStream(fileName, {
  encoding: 'utf8',
  bufferSize: 1024
})
let myIterableAsyncStream = MakeStreamIterable(readStream)

for (let data of myIterableAsyncStream) {
  let str = data.toString('utf8')
  console.log(str)
}

I'm not interested in co or bluebird's coroutine or blocking with deasync.

The gold is MakeStreamIterable should be a valid function.

like image 823
Jacob Avatar asked Oct 02 '15 07:10

Jacob


2 Answers

2020 Update:

It looks like streams will be "natively" iterable in the future - just waiting on browsers to implement it:

  • https://streams.spec.whatwg.org/#rs-asynciterator
  • https://github.com/whatwg/streams/issues/778
  • https://bugs.chromium.org/p/chromium/issues/detail?id=929585
  • https://bugzilla.mozilla.org/show_bug.cgi?id=1525852
  • https://bugs.webkit.org/show_bug.cgi?id=194379
for await (const chunk of stream) {
 ...
}
like image 57
joe Avatar answered Oct 05 '22 23:10

joe


Soon you are going to be able to use Async Iterators and Generators. In node 9.8 you can use it by running with --harmony command line option.

async function* streamAsyncIterator(stream) {
  // Get a lock on the stream
  const reader = stream.getReader();

  try {
    while (true) {
      // Read from the stream
      const {done, value} = await reader.read();
      // Exit if we're done
      if (done) return;
      // Else yield the chunk
      yield value;
    }
  }
  finally {
    reader.releaseLock();
  }
}

async function example() {
  const response = await fetch(url);

  for await (const chunk of streamAsyncIterator(response.body)) {
    // …
  }
}

Thanks to Jake Archibald for the examples above.

like image 32
Eduardo Avatar answered Oct 05 '22 21:10

Eduardo