Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async iterator support #3

Closed
sindresorhus opened this issue Nov 27, 2017 · 7 comments
Closed

Async iterator support #3

sindresorhus opened this issue Nov 27, 2017 · 7 comments

Comments

@sindresorhus
Copy link
Owner

Could be a nicer way to handle multiple events:

for await (const data of emitter.on('馃')) {
     console.log(data);
}

Spec: https://github.com/tc39/proposal-async-iteration

@bvx89
Copy link

bvx89 commented Dec 4, 2017

Maybe I don't understand this correctly, but how would one unsubscribe from these events?

@dinoboff
Copy link
Contributor

dinoboff commented Dec 4, 2017

By breaking out of the loop.

But I don't think it's a good fit. Emitter push data, while you pull data from an Iterator. To work the emitter would have to either queue events or to skip events emitted while the async loop block is getting processed.

@sindresorhus
Copy link
Owner Author

@dinoboff It would queue events. That's how Emittery works already though, as events are emitted async, so they're placed on the event loop (queue). It's probably not useful for the common case, true, but sometimes I just want to gather a certain amount of events from an emitter or all, and then iterating like this would be a nice way of handling it.

@novemberborn
Copy link
Collaborator

Weak references would allow the iterator to be garbage collected, and thus the queue as well. Support for that is probably still a long way off though.

@dinoboff
Copy link
Contributor

dinoboff commented Dec 4, 2017

@sindresorhus they are queued to some extends but the queue get flushed on the next tick whether the consumer is ready or not.

@dinoboff
Copy link
Contributor

dinoboff commented Dec 4, 2017

@bvx89 It would be something like that

function iterator(emitter, eventName) {
  return {
    async *[Symbol.asyncIterator]() {
      const queue = [];
      const off = emitter.on(eventName, (data) => queue.push(data));

      try {
        while (true) {
          if (queue.length == 0) {
            await emitter.once(eventName);
          }

          yield queue.shift();
        }
      } finally {
        // Called once the iterator result `return` or `throw` methods are called;
        // e.g. if the loop block `break` or `throw`.
        off();
      }
    }
  }
}

@sindresorhus
Copy link
Owner Author

Fixed by #40

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants