0

I am using this library https://www.npmjs.com/package/event-iterator to use async iterators. I have the following function

export function grpcClientReadableStreamToAsyncIterator<T>(
  stream: grpc.ClientReadableStream<T>
): AsyncIterable<T> {
  return new EventIterator((queue) => {
    stream.addListener("data", queue.push);
    stream.addListener("close", queue.stop);
    stream.addListener("error", queue.fail);

    return () => {
      stream.removeListener("data", queue.push);
      stream.removeListener("close", queue.stop);
      stream.removeListener("error", queue.fail);
      stream.destroy();
    };
  });
}

I have a function which uses it as follows

export function subscribeMyServicePromise(): AsyncIterable<TrieProof> {
  return grpcClientReadableStreamToAsyncIterator(
    <some function which returns grpc.ClientReadableStream>
  );
}

When I try to use in an async function like this

(async () => {

     console.log("here");
    let myAsyncIterableObj: AsyncIterable<MyObj> = await subscribeMyServicePromise()
    for await (const tp of myAsyncIterableObj){
      console.log("processing: ");
    }

    console.log("now here");
}()

It just prints the following and exits

here
processing: 
processing: 
processing: 
processing: 

My question is why is not printing "now here". Looks like the process ends after the for await loop ends. How can I avoid this?

EDIT

I could do this

const iterator = myAsyncIterableObj[Symbol.asyncIterator]()
    await iterator.next();
    await iterator.next();
    await iterator.next();
    await iterator.next();
console.log("now here")

and it works fine. Is there any problem with my way of writing for-await?

kosta
  • 4,302
  • 10
  • 50
  • 104
  • This is a quirk of NodeJs. It will wait for pending timers, but not for unresolved promises. I think it's a similar case to this question: https://stackoverflow.com/questions/10551499/simplest-way-to-wait-some-asynchronous-tasks-complete-in-javascript – user2740650 Jun 22 '20 at 03:29
  • @user2740650 - It's not a quirk. It's how things are designed on purpose. If there was an actual asynchronous operation associated with those promises (which there would be in any real reason for using promises), then node.js would be waiting to exit for the actual asynchronous operations. – jfriend00 Jun 22 '20 at 04:13
  • Is there an actual asynchronous operation still pending when nodejs exits? I'm not talking about a promise, I'm talking about an actual asynchronous operation like a timer, networking operation, file operation, etc... Nodejs will exit as soon as it gets back to the event loop and there are no more actual asynchronous operations pending. – jfriend00 Jun 22 '20 at 04:31
  • The original function inside which the `for-await` is running in an async function. Is that what you're referring to? – kosta Jun 22 '20 at 04:48
  • You'd have to show all the code that's executing here for me to be able to offer further advice. But, any real asynchronous operation that is not yet complete and has not been manually `deref()` will keep nodejs from automatically exiting. Once that asynchronous operation is done, all bets are off and if you go back to the event loop with no other asynchronous events pending, then nodejs may exit. – jfriend00 Jun 22 '20 at 05:41

0 Answers0