Using break in for-await-of without ending the underlying stream
Asked Answered
S

1

7

In a Node.js project, I am using a for await of loop with a readable stream as data source, so my code conceptually looks like this:

for await (const item of readableStream) {
  // ...
}

The readable stream exists before the loop, i.e. it does not get created for the loop, but it is already there. Now the point is that I would like to be able to stop listening to this stream, i.e. I would like to break from the loop, but I do not want to close the readable stream.

If I simply do this:

for await (const item of readableStream) {
  if (condition) {
    break;
  }

  // ...
}

the loop stops as expected, but the stream gets closed. How can I achieve the same thing, without closing the stream?

I can't use on('data') directly, because the action I want to take includes running an async function, and hence this won't work. I know that I could solve this using a Transform or a Writable stream, but this seems to be some overhead I would like to avoid.

Is what I want to do possible with a for await of loop, and if so, how? If not, what is my best alternative?

Semblable answered 6/4, 2019 at 21:49 Comment(2)
You could possibly use something like github.com/sindresorhus/p-event on data. Does this result in desired behaviour?Rickey
This has worked 😊… if you turn your comment into an answer, I will happily accept it!Semblable
R
5

It's possible to achieve this behaviour by listening data event with promisified event emitter.

p-event supports asynchronous iterators for this purpose:

const asyncIterator = pEvent.iterator(readableStream, 'data', {
  resolutionEvents: ['finish']
});

for await (const item of asyncIterator ) {
  if (condition) {
    break;
  }

  // ...
}
Rickey answered 7/4, 2019 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.