leebyron / iterall

🌻 Minimal zero-dependency utilities for using Iterables in all JavaScript environments.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AsyncIterator vs Observable?

OliverJAsh opened this issue · comments

Hi @leebyron. I just discovered this library, and enjoyed reading the docs. I hope to use it the next time I write a library, so thanks. :-)

One thing I noticed in the docs was that AsyncIterator is stated as similar to Observable: https://github.com/leebyron/iterall#why-use-asynciterators

AsyncIterator is similar to Observable or Stream.

AsyncIterator provides a common interface over a stream (or Observable) of values

I'm worried that this statement could be misleading, but my thinking here could be wrong.

I've been thinking a lot about the differences and similarities between iterables, async iterables, and observables (which are sync and async):

  • They have different conceptual models:
    • iterable is pull
    • observable is push
    • async iterable is both? (pull to request, push to receive);
  • They are related and complement each other. For example, a generator is an iterator and an observer.

Others can describe this much better than I can: tc39/proposal-async-iteration#25 (comment)

I would love to get your thoughts on this. Do you think they are indeed similar, or should they be considered separate concepts with different use cases?

Good point - I'm happy to update the readme to make this more clear. My goal is to introduce the concept of AsyncIterator to someone who might not have heard about it in terms of concepts they may already know. AsyncIterator is definitely not identical to Stream or Observable, but it often solves the same kind of problems those are used for.

Do you think they are indeed similar, or should they be considered separate concepts with different use cases?

Similar yes, but also each has its strengths which lead different tools for different use cases.

For example, while AsyncIterator can model a Stream (with backpressure!) but only for whole values, where a Stream typically manages a byte buffer which is definitely what you want when you're moving byte buffers around. The comment on that tc39 issue makes this point really well, I think.

Observable though I see as really similar to AsyncIterable, just lacking the ability to buffer or apply backpressure. The comment on the tc39 issue makes this sound like a positive for Observable for dealing with real-time data or UI events, but in my opinion it's just a tradeoff. You can certainly use AsyncIterable for real-time data or UI events - and having backpressure management via next() may be beneficial for dropping or merging events to not overwhelm the eventual consumer - however the tradeoff is that ignoring backpressure entirely may result in memory issues.

I'm going to close this issue - but feel free to continue discussion