I want to like generators for asynchronous code, but the one thing that disappoints me about generators is how awkward it is to write code that does the same as an async.auto
I use async.auto because of the ease of adding new asynchronous functions that depend on one or more other asynchronous functions having been executed beforehand.
Simply put you can break up a task into steps that depend on each other, and the steps run whenever all their dependencies have been executed. You don't have to worry about whether the functions run in series, or parallel, you just define that one function depends on another and it just works.
I have yet to see a promise example, or a generator example that had the combination of maintainability and legibility that an async.auto has. What I really want to see is a reasonably complicated task that has say 8 or more asynchronous steps mocked out in generators. Say something like:
Post a social item
1) Write social item to database
2) Write reference to social item in feed of person who posted item
3) Fetch friends of user who posted item
4) Fetch notification settings of each friend
5) Add a reference to the social item to each friend's personal activity stream
6) Based on notification settings of each user send an email alerting each friend of the event
7) Invalidate activity stream cache key for poster, and friends
In this flow:
1 & 3 can run in parallel at the start as they don't depend on anything
2 & 5 can run as soon as 1 is finished as they depend on the ID of the object in #1
4 & 5 can run as soon as 3 is finished as they depend on the friend list
6 can run as soon as 4 is done as it needs to know who to email and who not to email
7 can run as soon as 2 & 5 are done as the streams must be updated before the cache can be cleared
With async.auto it is easy to create 7 async functions and define the dependencies, then sit back and watch it run efficiently and magically. Later if you need to add more actions it is easy to insert another function, define what it depends on and see it working.
I still don't understand how to do something like this with generators, and none of the examples I've seen so far is complex enough, nor do they seem to solve this problem in a format as clean as async.auto
I didn't realize they doubled as both iterables and observables. Being able to pass a value in is a useful trick, although it looks a bit annoying to forward passed in values *due to error/return requiring try-catch shenanigans).
This can't be about backwards compatibility. If it was, they wouldn't have been able to add 'yield, 'await' etc.
I don't agree the keyword "generator" would have been ideal. It wouldn't work when using 'enhanced object literals' [1], where you can declare a method without even using the keyword "function". In this case, if you want the method to be a generator, you can just put an asterisk in front of its name, so it's consistent with the "function*" syntax.
It's only valid as a keyword within the `function*` block, so the parser can treat it as an identifier elsewhere. I haven't read the detailed spec, so I'm not sure that this is the standard behavior, but this would be a way to preserve complete backward compatability.
Yes, that’s how it works. `yield` is only reserved in ES5 strict mode. But due to it only being a keyword inside generators, there are no problems in non-strict mode.
It's the other way around. ES6 needs to support loading ES5 content. They can't make 'generator' a keyword because it was a perfectly fine variable name in ES5.
AFAICT, `async function` is OK, because you combine a keyword with something that is contextually turned into a keyword. With a single non-keyword that isn’t possble. For example, the following code (a hypothetical ES6 anonymous generator expression) could be an ES5 function call followed by a code block.
That's why it wasn't included in the ecmascript 6 draft. In es6, "async" and "await" are future-reserved keywords. It's kind of a process of marking variables named "async" as deprecated. The spec authors have to balance compatibility with making the language pleasant to use.
I don't think googling is much of an issue here. Unless you're talking about the very first occasion that someone sees "function*", then OK, they can't google for that easily... But they can google "function with astersik" or something and they'll find out it's called a "generator", and use that in future.
An unpopular opinion on a post about JavaScript maybe, but C#, Python, and others have implemented generators with no extra syntax because of an actual type system aside from "object, number, string, bool".
As Python has had generators for years already there is plenty of resources out there for the curious that translate well to ES6[0].
[0] http://www.dabeaz.com/coroutines/