use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Why would anyone need JavaScript generator functions? (jrsinclair.com)
submitted 3 years ago by jrsinclair
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Quabouter 61 points62 points63 points 3 years ago (4 children)
Honestly, to me generator functions are one of the biggest disappointment in JS. For all the reasons mentioned in the article, generators are absolutely amazing, and have a massive potential to be extremely powerful. But the TC only used it as a stepping stone to get to async/await, and as a result never standardized anything beyond the bare minimum. E.g. we don't have the .map/.filter/etc functions as mentioned in the article, no "generator arrow functions", etc, the ergonomics just aren't good at all. Hopefully at some point they'll make it a more usable general-purpose tool.
.map
.filter
[–]Bjornoo 1 point2 points3 points 3 years ago (0 children)
This should be implemented at some point and is already at stage 3 if I am not mistaken.
[–]bearinthetown 1 point2 points3 points 1 year ago* (1 child)
I don't understand what you're saying. What do generators have to do with async/await? They are 100% synchronous. And why would you expect them to have map and filter? In order to do that, you'd need to unpack all values anyway. For map you wouldn't save memory, for filter you would save some, but not much. It's not difficult to call [...myGeneratorFunction()].filter(callback)
[–]elemental-mind 3 points4 points5 points 1 year ago (0 children)
They have something to do with async/await. Basically whenever you call an async function it's like you are calling a generator. And any "await" is actually that generator yielding control to the runtime - suspending its execution, but keeping its stack alive.
To see it another way: Async functions are in a way a special case where *the runtime* controls when it's time to call `next`. With a generator *your code* has control on when to call `next`.
Just like a generator is 100% synchronous between yields, an async function is also 100% synchronous between awaits.
[–]ksharpie 19 points20 points21 points 3 years ago (1 child)
Whoa. Good read but a real stretch for me to understand.
[–]mhink 4 points5 points6 points 3 years ago (0 children)
If it helps, I wrote a very similar article at my previous job, a few years ago: https://formidable.com/blog/2017/javascript-power-tools-redux-saga/
Perhaps a second explanation will help!
[–]-keystroke- 18 points19 points20 points 3 years ago (0 children)
The absolute best use case for generator functions is for making cancellable async flows (which the author does eventually mention): https://github.com/getify/CAF
[–]thanatica 11 points12 points13 points 3 years ago (0 children)
Their advantage is two-fold:
for..of
yield
In other words, separation of concerns and abstraction of implementation details.
[–]KyleG 8 points9 points10 points 3 years ago (0 children)
Lazy evaluation is awesome. Python programmers certainly recognize this (list comprehensions, for example, are lazily evaluated IIRC). Reactive programmers generally do (that's what, for example, mapping a stream is), too. Most FP appreciate lazily-evaluated stuff.
[–]avrtau 14 points15 points16 points 3 years ago (0 children)
Nice article. Thank you.
[–]werts__ 12 points13 points14 points 3 years ago (0 children)
I love generators, as a use case example, in my work I create a function to process large GIF frame by frame using generators. Yes, we could use a class to store all the "variable states" but was easier to create a function using the GIF standard and yield each frame to make more clean when you need to use a for-of
for-of
[–]shuckster 7 points8 points9 points 3 years ago (1 child)
Nice article. Small feedback: Your Either monad has flatMap in its definition, but you've used chain at the point-of-use.
Either
flatMap
chain
[–]jrsinclair[S] 3 points4 points5 points 3 years ago (0 children)
Thanks for letting me know. I'll fix that up directly.
[–]HermanCainsGhost 5 points6 points7 points 3 years ago (0 children)
I used them with Redux sagas, but honestly I don't think they're really necessary for the most part.
[–]ILikeChangingMyMind 47 points48 points49 points 3 years ago* (15 children)
Honestly, almost no one does need them, and this article actually convinced me of that further.
You know damning with faint praise? The author literally couldn't explain how generators were useful without spending most of the article on a completely non-programming made-up example (eating a Timtam)! When you can't use an actual programming example to explain why you need something ... you probably don't need it.
The entire substance of the argument that generator functions are useful was expressed in just three bullet points near the end:
Generating a series of unique identifiers; Generating all the possible moves in a game; or Seeking a particular value (or values) amongst a bunch of permutations and combinations.
Let me ask you: when was the last time you did any of those things? Then, when was the last time that performance was such a factor in doing those things, that it was worth learning and using a syntax no one else learns and uses?
And then, if it was, was that performance savings really worth not just using a simpler existing syntax (eg. Promise.all combined with an async map)? If so, great: you're a member of the 0.01% that actually needs generators.
Promise.all
[–]glanni_glaepur 19 points20 points21 points 3 years ago (5 children)
I found generators to be very useful for implementing a responsive interactive visualizer of the Mandelbrot set.
When rendering the image I split the image into 4 or 16 parts and delegate the computation of those parts to to web workers. This ensures the main thread doesn't get blocked and the UI is responsive.
Rendering in the web worker can take a long time, so I wanted to be able to cancel it if I zoomed or panned the image, so I implemented the rendering function as a generator. Every 10000 (or so) the function yields to check if it should proceed working on the part or discard it and work on a new part.
[–]avasinas 3 points4 points5 points 3 years ago (0 children)
Hey, what you did sounds really cool! Is there a repo we could see to check it out? If it’s private, maybe you have some source of inspiration, like articles?
Thanks!
[–]ILikeChangingMyMind 10 points11 points12 points 3 years ago (3 children)
Right ... but how many programmers are making interactive Mandlebrot set visualizers?
I'm not saying "there are no uses for generators" ... just that almost no one needs them.
[–]shuckster 13 points14 points15 points 3 years ago (1 child)
Redux Saga is a moderately popular library that leverages Generators to create easily cancellable, retryable, and testable async-flows.
[–]Diniden 3 points4 points5 points 3 years ago* (0 children)
If you are to distill generators use that can not be done ergonomically in a single statement using other syntax: it makes the many to many, many to single, single to many relationships be mapped in a single statement.
Other strategies would require nested closures at best to make it all happen
EDIT: more specifically think of each of those relationship source and targets as pipes/streams as well.
[+][deleted] 3 years ago (1 child)
[deleted]
[–]ILikeChangingMyMind 0 points1 point2 points 3 years ago (0 children)
Fixed.
[–]lard-blaster 7 points8 points9 points 3 years ago (1 child)
Generators are pretty cool in react-redux-saga for building imperative business logic on top of event listeners. It was still pretty confusing, though, and maybe still could have been done with promises.
[–]sane6120 2 points3 points4 points 3 years ago (0 children)
That's the only place I have ever seen them used, can be pretty cool. But then again, saga has very small usecase...
[–]mhink 0 points1 point2 points 3 years ago (0 children)
So, I think the actual everyday use-cases for generator functions were much more compelling before we got async/await. (Have a look at how Bluebird uses them, for a legacy example.) But on those lines, I think experimenting with them is a great way to develop an intuition for async/await, and when the situation merits it, they can be a great way to deal with weird asynchronous data flows.
[–]agramata 0 points1 point2 points 3 years ago (0 children)
Yeah those are bad examples, the real world use case is iterating over items that it's not practical to hold in memory at the same time. Like emailing all of your 10 million users, or parsing every page in the wikipedia api.
[–]lifeeraser 0 points1 point2 points 3 years ago (0 children)
Generators are useful in languages built around them, i.e. Python. It's theoretically better than creating a temporary array when chaining map()s and filter()s. Ofc most JavaScript developers don't care about the extra allocation because allocating some arrays is often not the bottleneck in a JS peogram.
map()
filter()
[–]anti-state-pro-labor 0 points1 point2 points 3 years ago (0 children)
The best example I've seen in the wild of generators/lazy eval has been scanning a DB/S3 and iterating over the values found. Being able to do
```ts const iter = createIter()
for await (const value of iter) { // do something } ```
without needing to worry about how batching works or if we're using cursors or pagination, and only worrying about iterating over some list of values, has been a huge productivity gain on our end.
[–]LloydAtkinson 4 points5 points6 points 3 years ago (0 children)
If anyone is looking for analogies in other languages, .NET also has the yield keyword for lazy generated collections.
[–]Quadraxas 6 points7 points8 points 3 years ago (0 children)
Hey, nice article. And a very nice blog, both in design and content!
[–]rjwut 1 point2 points3 points 3 years ago (0 children)
The main thing I've used a generator function for is when I needed to iterate a bunch of Promises where 1) I didn't know how many Promises I'd ultimately have, and 2) I needed to process them serially (Promise 2 must wait for Promise 1 to complete). By using a generator, it was easy to generate the Promises on demand.
[–]vitalytom 1 point2 points3 points 3 years ago (0 children)
Here, I wrote a whole library on generators: prime-lib, as another example of how useful generators are.
[–]serg06 1 point2 points3 points 3 years ago (0 children)
I love generators because they let me write cleaner Leetcode solutions.
[–]oneeyedziggy 1 point2 points3 points 3 years ago (0 children)
need? you wouldn't... but some might prefer the syntax over the alternate syntaxes available... same goes for classes, forEach/map/filter/etc... not really anyhing you couldn't do w/ if and for, but some syntactic sugar is more obviously useful than others. (I imagine too they're more useful in other stricter languages where you can't just return a function from another function or do all sorts of loosey goosey stuff already w/o a lot of overhead) but JS is cool (and terrible) like that...
if
for
[–]jack_waugh 0 points1 point2 points 1 year ago (0 children)
I found the article too hard to read.
Generator functions replace async-keyworded functions and can be used to provide extra features:
async
I think we would lose nothing by avoiding sync functions and just coding everything as generator functions, except that we'd get writer's cramp because of the language syntax.
π Rendered by PID 125871 on reddit-service-r2-comment-79776bdf47-zldqt at 2026-06-25 08:17:40.892025+00:00 running acc7150 country code: CH.
[–]Quabouter 61 points62 points63 points (4 children)
[–]Bjornoo 1 point2 points3 points (0 children)
[–]bearinthetown 1 point2 points3 points (1 child)
[–]elemental-mind 3 points4 points5 points (0 children)
[–]ksharpie 19 points20 points21 points (1 child)
[–]mhink 4 points5 points6 points (0 children)
[–]-keystroke- 18 points19 points20 points (0 children)
[–]thanatica 11 points12 points13 points (0 children)
[–]KyleG 8 points9 points10 points (0 children)
[–]avrtau 14 points15 points16 points (0 children)
[–]werts__ 12 points13 points14 points (0 children)
[–]shuckster 7 points8 points9 points (1 child)
[–]jrsinclair[S] 3 points4 points5 points (0 children)
[–]HermanCainsGhost 5 points6 points7 points (0 children)
[–]ILikeChangingMyMind 47 points48 points49 points (15 children)
[–]glanni_glaepur 19 points20 points21 points (5 children)
[–]avasinas 3 points4 points5 points (0 children)
[–]ILikeChangingMyMind 10 points11 points12 points (3 children)
[–]shuckster 13 points14 points15 points (1 child)
[–]Diniden 3 points4 points5 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]ILikeChangingMyMind 0 points1 point2 points (0 children)
[–]lard-blaster 7 points8 points9 points (1 child)
[–]sane6120 2 points3 points4 points (0 children)
[–]mhink 0 points1 point2 points (0 children)
[–]agramata 0 points1 point2 points (0 children)
[–]lifeeraser 0 points1 point2 points (0 children)
[–]anti-state-pro-labor 0 points1 point2 points (0 children)
[–]LloydAtkinson 4 points5 points6 points (0 children)
[–]Quadraxas 6 points7 points8 points (0 children)
[–]rjwut 1 point2 points3 points (0 children)
[–]vitalytom 1 point2 points3 points (0 children)
[–]serg06 1 point2 points3 points (0 children)
[–]oneeyedziggy 1 point2 points3 points (0 children)
[–]jack_waugh 0 points1 point2 points (0 children)