
Async JavaScript Generators - michaelsbradley
https://www.bignerdranch.com/blog/asyncing-feeling-about-javascript-generators/
======
mwpmaybe
Generators are used to great effect in Ember thanks to the ember-
concurrency[0] addon. It was far and away the most frequently talked-about
topic at EmberConf last week. If you're interested, I'd highly recommend
machty's talk[1] from last year where he introduced it. His talk from last
week was also very good, but it does not appear to be available yet.

I don't think it's currently using async generators (have yet to read the
linked article), but I suspect this new language feature may lead to some
improvements!

0\. [http://ember-concurrency.com](http://ember-concurrency.com)

1\. [https://vimeo.com/162329769](https://vimeo.com/162329769)

~~~
kabes
Is it only usable as an ember addon in the browser?

It seems like this would be useful as a stand-alone library for node.js
projects.

~~~
mwpmaybe
To the best of my understanding, yes, it's pretty well tied to Ember. Other
options (such as redux-saga mentioned in a sibling comment) may be a better
fit.

------
partycoder
Every async operation can potentially fail. And one obvious way is: a timeout.
It is very unlikely you want your async operation to last forever. So
sometimes you need to specify that timeout and clean up everything afterwards
(e.g: close handles to files or connections, unsubscribe event handlers, or
anything necessary to not produce a leak), as well as log whatever happened
and propagate errors in a controlled manner.

Having this said, what is very lacking in most programming blog posts is the
error handling portion, which is important. Errors happen all the time, and
nothing is 100% reliable. Hardware is unreliable, networks are unreliable,
input is unreliable... And this needs to be reflected in your code.

Some communities understand that code snippets from blog posts are not
production code. But doesn't seem to be the case in the node community.

The impact of that is that is that now:

\- npm is full of modules that do not handle their own errors

\- many node applications lack robustness, bringing back reputation to node.
e.g: not taken seriously as a platform language just as a throwaway
orchestration layer and doing monkeying with JSON.

\- lack of error handling is mistakenly seen as elegance and simplicity. in
reality it's lack of skill, seniority and responsibility

\- node module descriptions have more happy emojis and hyped superlatives than
actual useful descriptions of how error conditions are handled

\- consuming a node module today is playing Russian roulette each time you
upgrade a version

I really hope the community takes a turn towards making code more robust and
that could start in the blogosphere, talks, etc. But javascript is now the
lingua franca of people that do not care about error handling and that is sad.

~~~
AgentME
Did any of the code in the article not handle errors? Everything was using
Promises and async functions which automatically have error progration handled
for you.

~~~
partycoder
In the article, the errors may propagate but there is no error handling or
timeout.

------
inglor
Hey, here is a talk I gave about rewriting Rx with async iterators (a complex
example is shown) -
[https://docs.google.com/presentation/d/1nAi7fTa2K9XUIDSG7Bg1...](https://docs.google.com/presentation/d/1nAi7fTa2K9XUIDSG7Bg1XZw7tr0RgGpurqjVq2iDebs/edit?usp=sharing)

~~~
Matthias247
Nice presentation. I have used Rx in some previous projects, however for new
things I now also prefer pull-style APIs with possible async/await like you
have shown. From my point of view they are easier to comprehend (more normal
syntax instead of magic operators), easier testable (less callbacks in tests)
and allow a better ingeration overall (e.g. you can move ownership of the
object which is iterated upon between components without doing things like
complete/unsubscribe and caring about whether it's a hot observable and
unsubscription might loose events).

One remark about your slides: Your implementation of "throttle" might not be
what one would expect from a debounce/throttle function, as it will never emit
the last value if this is filtered (shortly occurs after a previous one). In
most applications the last value of an eventstream is important, as it
represents the most recent / final state. E.g. for the example which makes
HTTP queries out of form data you would never make a query for the final text
content if the last keystroke happenend in the debounce period for the
previous one.

------
michaelsbradley
I'm curious whether the patterns explored have found application in a redux
middleware[1] approach that builds on or is inspired by redux-observable[2]
and/or redux-saga[3]. I've been searching around since reading the OP, but no
joy so far.

[1]
[http://redux.js.org/docs/advanced/Middleware.html](http://redux.js.org/docs/advanced/Middleware.html)

[2] [https://redux-observable.js.org/](https://redux-observable.js.org/)

[3] [https://redux-saga.github.io/redux-saga/](https://redux-
saga.github.io/redux-saga/)

~~~
clearing
Most of these patterns are eventually implemented in a production redux-saga
application (at least in my experience, with React Native). Things like
eventChannels are fairly similar, if not abstracted away a bit

------
jaequery
i love js. but i feel js is getting more and more uglier by the day. in my
early days, i would have been excited for all the cool new syntaxes that comes
out, i for one wished some of the new syntaxes and changes we now have more
than 8 years ago. but as i get older, i start appreciating the languages and
frameworks that takes the simple and elegant route. the beauty of languages
comes from simplicity. anyone can throw a bunch of things to make something
work but takes lot of thought and pragmatism to make it look and feel simple.

i think the js fatigue is real and while async await is great and heading in
the right direction, it will be some time and evolution for it to be where
everyone will accept it as elegant.

~~~
replete
Did you read the article

~~~
johnsonjo
Yeah I agree with you here. I was amazed he was able to make a RxJS look a
like in such few lines of code using async iterables. It looks like a really
nice addition to the language for those who already love FRP concepts.

~~~
pygy_
Streams can be implemented with functions as well, no need for async
generators. See `flyd` or `mithril-stream`...

------
thosakwe
All I'm saying... Dart has had asynchronous generators for years.

Really awesome article, though, and very well-written.

~~~
spankalee
And 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
Async 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-
itera...](https://github.com/tc39/proposal-async-iteration#async-iterators-
and-async-iterables) [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
Rauschmayer looked at the different roles back in Oct '16:

[http://2ality.com/2016/10/asynchronous-
iteration.html#altern...](http://2ality.com/2016/10/asynchronous-
iteration.html#alternatives-to-async-iteration)

~~~
johnsonjo
Thanks for the link. Rauschmayer is a superb teacher through his blogs, I
would definitely take his words over my own.

