In one of my many deep-dives about JavaScript, I came across generators. They looked interesting.
Then, I looked for some use-cases for generators...
For further actions, you may consider blocking this person and/or reporting abuse
I've found some more cases personally that have actually helped and are much smaller examples. My 3 favorites are:
Generators also help to loop through structures where you'd normally need to keep track of multiple variables at a time. Instead of having multiple pieces of global state, you just need to call
.next()
on the generator.I'd like to hear more about generators being a mistake though. I haven't yet heard that and I would like to know the reasoning behind it.
Cheers!
Can you provide "practical" code uses with your examples that I can include?
Here is the first example (looping arrays using generators to pause and resume):
Here is the infinitely looping array:
Here is how to make an iterable from an object:
and using a similar method, you can convert objects to Maps, which can become super useful in some instances:
OK, the code examples are good ... and I get where you are going with this.
By "practical," I am trying to find actual use-cases ... not just "Hello World" type of code.
I'm not going to bootstrap an entire project for an example, but I can give you a basic use case for them:
.includes()
I hope you understand that I'm not going to code these entire use cases. It's be much too long for a comment and I'd sooner make my own post than a comment with the full code.
This is more than enough ... if you are OK with it, I'll do a follow-up post to this one with your examples included (attributed to you, of course) down the road.
Sounds good.
If you want one or two more, Dr. Axel Rauschmayer provides some use cases with async code
Awesome ... thanks for the additional references!
@emnudge regarding your examples:
Could you explain / demonstrate 4. ?
I'm also not sure if I understand 3.
Why not use object.values().includes() ?
Hey there! Just saw this now.
We can iterate through objects in many ways. The demonstration was showing that we can also iterate through objects in particular ways, as per our own use case.
We might want to create an iterator that only spits out object properties that are numbers or fall under some filter.
We could create an array of all properties and then filter, but this is creating 2 arrays whereas a generator allows us to create 0 arrays. We simply iterate over the returned iterable and deal with it as necessary
I love the idea of using a generator for this. I might have to try an alternate!
Love the comments.
As to Generators being a mistake, I heard that in a talk a while back and vaguely remember agreeing with the arguments at the time. Since I can't remember the talk or the arguments, I'll change the language here.
Thanks again!
Bob
Let me share an example using async generators that I recently implemented.
tl;dr: async generators for streaming
I had to find all people who have commented on issues at a particular GitHub repo. GitHub's rest API provides us with an endpoint that can list issue comments. With each page having a few results, in order to find all the commentors, we have to traverse all the pages. Now we can do this in a single run, and then show user the results, which will take really really long time of user seeing nothing (on a repo with 250 pages, it took 5-6 min). What can be better for user experience is to keep emitting unique commentors as we find them, hence creating a streamed output so user knows things are really in progress and not broken.
You can find the code for this at: github.com/sidvishnoi/respec-githu... and github.com/sidvishnoi/respec-githu...
Can't wait to see the code!
The first example can be done using just a simple plain old function. Why would you use generators for that?
It's even less code than the generator example. I'm sure the other examples can be done without generators too.
This article was more about the generators ... and how they can be used, not proving it better or worse than traditional methods. The idea wasn't to come up with examples that couldn't be done in regular JavaScript. The idea was to come up with examples of practical generator usage.
Yes, some of these examples can be done in Vanilla JS. But, given the generator's ability to be a "state machine," it can provide a more elegant solution in a few cases ... although, again, that was not the focus of the article.
You left out combining the generators API with
Symbol.iterator
to create an object which can be used with the browser's native for/of syntax. developer.mozilla.org/en-US/docs/W... Which, from my perspective, is the most obvious/common use case for generators.Separately, the open source recurring dates library rSchedule is built entirely upon ES6 generators. They are a necessary abstraction given that many calendar schedules are infinitely recurring.
Pretty much every object in the library is a generator. The generator code for the
Rule
object can be seen here: gitlab.com/john.carroll.p/rschedul....When you build out a recurrence object in rSchedule, you are really building a generator out of many generators.
Didn’t leave out the Symbol.iterator ... was looking for “practical” use-cases. Can you show, in code, a use case beyond the Hello World examples?
For the rSchedule ... THAT is what I was looking for. Can’t wait to dig through their code!
I'll let rSchedule be my practical example.
Though I'm getting the impression that we might have different conceptions of the word "practical". From my perspective, a
for
loop is one of the most basic javascript keywords. Used in pretty much every app ever. The practicality of being able to hook into that keyword (and related keywordscontinue
andbreak
) with a custom object seems self evident? Or are you more simply wondering why someone wouldn't just extendArray
(or expose the data as an array via a property)?I believe I might need to extend my definition of practical. I was looking for real-world use-cases since some of the examples seem challenging to see applied in production code. I’m trying to showcase code that is more than just an example.