3 ms·
All I'm saying... Dart has had asynchronous generators for years. Really awesome article, though, and very well-written.
by thosakwe 10y ago
All I'm saying... Dart has had asynchronous generators for years.
Really awesome article, though, and very well-written.
- spankalee 10y agoAnd Dart async generators return Streams, the one streaming async primitive. JavaScript async generators return "async iterators", which are like an iterator where next() returns a Promise. But JavaScript, in browsers at least, but I assume node will follow, will also have a separate Stream class used by fetch() and other I/O, with a different API where read() returns a Promise. And then, everyone seems to be clamoring for Observables, a third async streaming API. This is not going to be a great situation, 3 different async streaming APIs, so I'm sure some enterprising young coder will create a 4th API to wrap the other 3 in a common interface. Yay, JavaScript.
- johnsonjo 10y agoAsync iterables seem to be more like a unifying feature to me. For example the TC39 docs on async iterable say this: > Furthermore, we introduce a new symbol > used for obtaining an async iterator > from a given object, Symbol.asyncIterator. > This allows arbitrary objects to advertise > that they are async iterables, similar to > how Symbol.iterator allows you to advertise > being a normal, synchronous iterable. > An example of a class that might use this > is a readable stream. [1] So, the readable stream may end up implementing this api. I went to see if the same thing might go for the observable api. I found that they may have the ability of coercing async iterables with Observable.from()[2] or they could have the ability for asyncIterators to be used as observables through other methods [3]. Observables do implement their own Symbol.observable which does make them different. Really Observables do play a different role than async iterables though[3]. Something that makes observables different is they don't have to be asynchronous. As you may have noticed in the article Promises are added to a queue as micro-tasks where as observables can and will execute immediately if they have a value ready. Honestly we don't even know whether both or either of these will make it into the final spec. I personally hope they will make it. As long as there is strong interoperability it is fine with me, which as it is this seems to be the case. [1] https://github.com/tc39/proposal-async-iteration#async-iterators-and-async-iterables https://github.com/tc39/proposal-async-iteration#async-itera... [2] https://github.com/tc39/proposal-observable/issues/130 https://github.com/tc39/proposal-observable/issues/130 [3] https://github.com/tc39/proposal-async-iteration/issues/47 https://github.com/tc39/proposal-async-iteration/issues/47 [4] https://github.com/tc39/proposal-observable/issues/116 https://github.com/tc39/proposal-observable/issues/116
- michaelsbradley 10y agoRauschmayer looked at the different roles back in Oct '16: http://2ality.com/2016/10/asynchronous-iteration.html#alternatives-to-async-iteration http://2ality.com/2016/10/asynchronous-iteration.html#altern...
- johnsonjo 10y agoThanks for the link. Rauschmayer is a superb teacher through his blogs, I would definitely take his words over my own.
- spankalee 10y agoThe main differences between the three can be described along two axes: buffering/single-subscriber vs. non-buffering/multi-striver, and synchronous vs. asynchronous. You don't really need three separate interfaces for this. Dart's Streams can cover all cases depending on how you create the source StreamController. I asked some of the people behind the specs and they felt if was too complicated to have one interface cover the use cases. I tend to think it's more complicated now. I can't trivially write code to handle all interfaces without explicitly thinking and opting in to it.
- domenicd 10y agoHey there, I'm both the author of the browser streams spec [1] and the current champion of the async iteration spec [2] that this article discusses. We have, in fact, thought through the interaction here :). johnsonjo got things basically right in his response. We go into more detail in the streams FAQ, including the connection to observables: - "How do readable streams relate to observables or EventTarget?" [3] - "How do readable streams relate to async iterables?" [4] The basic punchlines are: > Observables and readable streams both share the semantic of "zero or more chunks, followed by either an error or done signal". But beyond that, they are not very comparable. and > The best analogy is something like "readable streams is to async iterable as array is to sync iterable." That is, just like arrays are a specialized type of iterable optimized for memory locality and random access, readable streams are a specialized type of async iterable optimized for things like off-main-thread data transfer and precise backpressure signaling. I do indeed expect us to start speccing the [Symbol.asyncIterator]() for readable streams, and shipping it (behind a flag at first) in Chrome, within the next month or so. [1]: http://streams.spec.whatwg.org/ http://streams.spec.whatwg.org/ [2]: https://tc39.github.io/proposal-async-iteration/ https://tc39.github.io/proposal-async-iteration/ [3]: https://github.com/whatwg/streams/blob/master/FAQ.md#how-do-readable-streams-relate-to-observables-or-eventtarget https://github.com/whatwg/streams/blob/master/FAQ.md#how-do-... [4]: https://github.com/whatwg/streams/blob/master/FAQ.md#how-do-readable-streams-related-to-async-iterables https://github.com/whatwg/streams/blob/master/FAQ.md#how-do-...