DEV Community

Cover image for 💡🎁 JavaScript Visualized: Generators and Iterators

💡🎁 JavaScript Visualized: Generators and Iterators

Lydia Hallie on January 16, 2020

ES6 introduced something cool called generator functions 🎉 Whenever I ask people about generator functions, the responses are basically: "I've seem...
Collapse
 
vaibhavkhulbe profile image
Vaibhav Khulbe • Edited

This visualization series is so good. I can totally relate to the context! Thank you for doing all the hard work 😁

PS: Like I said earlier, "better than my college professors!" 😛

Collapse
 
daviddaxi95 profile image
David Daxbacher

Very nice explanation and visualizations of the code. Well done. But I am still missing valid use cases where to use the generator functions in "real" applications, because your last example can also simple and efficient realized by using the es5+ features (flatMap and find):

const id = 'ey812';
const book = bookclubs
  .flatMap(club => club.clubMembers)
  .flatMap(member => member.books)
  .find(book => book.id === id);
Enter fullscreen mode Exit fullscreen mode

Maybe I have to explicitly search for some use cases and dive a little deeper into this topic, until I finally have the "ahhhhh" effect :)

Collapse
 
lydiahallie profile image
Lydia Hallie

Your example works when we already have the all data available (to give bookclubs a value) and for datasets that aren't too big. However, we would be storing the entire bookclubs array in memory, which is something we sometimes want to avoid when working with a lot of data which might be useless.

A good example for which I often use generators is decoding a stream. In your example, we'd have to wait before we've received the entire stream before we can start decoding it (in order to give bookclubs a value). By iterating over smaller pieces of the stream, and decoding these smaller pieces, we can already start decoding it right from the beginning instead of having to wait. If you're looking for a specific piece of data that may be right at the beginning of the stream, it means that we don't have to call next again and don't have to use more memory in order to store the rest of our data, which would be useless.

(Although this is a micro-optimization which doesn't matter in most cases, I'm also not sure about performance of flatMap when working with larger, deeply nested datasets.)

Collapse
 
tstsankov profile image
TSTsankov

const findbook = (bookID) => {
for(var i=0; i<members.length; i++)
for(var j=0; j<member[i].Books.length; j++)
if(members[i].Books[j].id == bookID)
return members[i].Books[j];
}

findbook("ey812");

Shouldn't the return statement just finish execution if/when book is found?

Thread Thread
 
iversonlv profile image
iversonLv

I think so, for loop seems the same flow with generator function for above book club example.

Collapse
 
daviddaxi95 profile image
David Daxbacher

Ok now i got the point, makes sense. Thanks! 👍

Collapse
 
iversonlv profile image
iversonLv

My understanding is if we use flatMap will flatMap the whole block of dataset? then find the book.id===id?

But if we use generator yield* iterateClubMember(bookClub.clubMembers)
Then if seems will like recursive first jump to index 0 of clubMmebers, and same step
yield* iterateBook(clubMember.books)
go in the index 0 index 0 books, if found books id===id, return?

The worse situation is we yield till end of the whole dataset, the perfect case is the id is 0 index of the 0index for clubMmmber, and got the book.

Am I correct?

Collapse
 
glencodes profile image
Glen Burnett

This is the most insane kung fu magic ever. Thank you for explaining this. Very useful. The visual animations are very good too, definitely think you would be struggling to explain it without the animations to assist :)

Collapse
 
thepeoplesbourgeois profile image
Josh

Teach them reduce, teach them reduce!

Collapse
 
jannikwempe profile image
Jannik Wempe

Wow, awesome work with all these animations (and emojis) 🆒! It really helps me understanding the concept. I think there would be no way of understanding it without visuals. Keep on that great work!

Collapse
 
imdanwu profile image
Daniel Wu

Hey love this series! This was one topic I had trouble diving into. Thanks!

Also, I think the last example has a small mistake. If the book you're looking for is the very last book, then the while loop will end before checking it.

Collapse
 
adegbengaagoro profile image
Agoro, Adegbenga. B

You know, I have read all the previous Visualized articles and I was like, "This is really great content" but I never commented until now.

This is by far the best content I have encountered about generators. In the past, I'd read everything I encounter about generators and be like, "someday it will all come together and I will get it".

This article wiped all that content out and gave me insightful and actionable knowledge.

Keep up the great work and your ability to distill the information, amazing!!!!

Collapse
 
lydiahallie profile image
Lydia Hallie

Thank you so much!

Collapse
 
moopet profile image
Ben Sinclair

Just a heads up that the Markdown we use here supports syntax highlighting, and is generally more accessible than inserting an image of code. Images of text are an issue for people using screen readers, for example, and their content won't get picked up by the site's search facility.

You can add code blocks with 3 backticks: code block with colors example More details in our editor guide!

Collapse
 
hugoliconv profile image
Hugo

What do you use to create those amazing animations?

Collapse
 
conermurphy profile image
Coner Murphy

Love this series and more importantly your blog posts. From someone, who is relatively new to the dev world these posts are a god send. I'd love to know what you make the animations in, would love to use it for similar stuff in my own blog posts. 🔥

Collapse
 
artoodeeto profile image
aRtoo

Ma'am, you are the GOAT! I'm telling you! You helped my brain cells.

Collapse
 
hcminhit profile image
i love Math

hi, I didn't understand everything you wrote starting from ". It's actually because they implement the iterator protocol: the [Symbol.iterator]. Say that we have the following values (with very descriptive names lol 💁🏼‍♀️) :"

Collapse
 
jsn1nj4 profile image
Elliot Derhay

I was doing a little exercise recently that this would've helped me very much on. Now I'll be able to simplify what I wrote very much. Thanks!

And yeah, I realize I'm reading this article late, but it's still just as helpful. This is pretty awesome. I bet there are a number of things I could refactor in a simpler way using these concepts...

Collapse
 
posandu profile image
Posandu

One thing how did you added those coding gifs ?

Collapse
 
gigamegs profile image
Gigamegs

Why not using break?

Collapse
 
hellovietduc profile image
Duc Nguyen

I have the same question. Still in the stage of "oh gosh no I've read so many blog posts about generator functions and I still don't get them"!

Collapse
 
belkinev profile image
Eugene

Wow! The topic I avoided so long. Thank you, Lydia

Collapse
 
wendyver profile image
wendyver

To @lydiahallie, or anyone else reading this, as I haven't seen many responses or engagement by the author lately. Well, first, Excellent article, and fantastic series! Very well done, and great explanations!!! Definitely makes things easier to understand. But my question is: DOES ANYONE KNOW WHERE I CAN GO TO MAKE THOSE CODE ANIMATIONS??? Is there an app, or something I can do in markdown? They make understanding challenging code sooooooo much easier! :Dx

Collapse
 
codenutt profile image
Jared

This is going to help to solve Project Euler problems, thank you!

Collapse
 
diek profile image
diek

Very nice series! Continue like this. I can say now that i understand generators :) TY!

Collapse
 
ikemkrueger profile image
Ikem Krueger • Edited

For me "yield" is a nothing more then a fancier "return" statement.

And in your generator example I would use one of find(), some(), filter(), reduce(), map().

Collapse
 
webpig profile image
朱宝华


clubs should be bookClubs

Collapse
 
silverbullet069 profile image
VH

Hmm but in my opinion, you normally don't iterate through a very big data sets which is loaded either in stream or in whole, and resides in a JS object like bookClubs, that jobs is delegated to a SQL distributed query engine, that way you can do it much much faster. Or there are other use cases that iterating inside JS is a must?

Collapse
 
oosharma profile image
Abhishek Sharma • Edited

I think there's maybe a minor correction, where you state that a Generator's return value is an iterator object since it follows the iterator protocol as they implement the @@iterator method stored in their key [Symbol.iterator] ... so, technically, an object follows the iterator protocol when they implement the next() method, and it follows the iterable protocol when it implements the @@iterator method.

By the way, I couldn't figure out when exactly can we call an object and iterator. What if an object implements just the next() method, or just the @@iterator method, will it be an iterator? Also, would it make sense to have just one of those methods ... I guess I'll keep reading more on it.

Anyways, thanks so much for posting such timeless, incredibly valuable, and easier to digest study materials :)

Collapse
 
fabricioffv profile image
Fabricio Filipe Viapiana

Hi Lydia
Does the iterators have more performance than array.filter/reduce on searching for data in a huge array? I mean, which one is the best, an interatior funcion or filter/reduce?

Collapse
 
hcminhit profile image
i love Math

hi please give me the source code of this

Collapse
 
suzettemccanny profile image
Suzette McCanny

This is so fun! Thank you!

Collapse
 
alimobasheri profile image
MirAli Mobasheri

Thanks for the article. I really like your approach. 👍

Collapse
 
hem profile image
Hem

This is great and it inspires me ❤️

Collapse
 
corentinbettiol profile image
Corentin Bettiol

I had already found the previous posts but I didn't have an account at the time.
Thank you for writing such wonderful posts!

Collapse
 
hcminhit profile image
i love Math

hi
you said: ", a generator function returns an iterator " so why do you also say that " [Symbol.iterator] has to return an iterator"? I don't understand, please clarify for me.

Collapse
 
geauxweisbeck4 profile image
Andrew Weisbeck

These are so cool @lydiahallie - how u dothis?

great style for real y'all.

Collapse
 
felix_zhou_aaea4b3085773d profile image
Felix Zhou

Don't now why some pictures do not exist

Collapse
 
holtkam2 profile image
Jason Holtkamp

Animations on point!

Collapse
 
weeshin profile image
weeshin

These GIFs are amazing, thanks so much for this great content😋

Collapse
 
rhymes profile image
rhymes

Love it! Great explanation and gifs :)

Collapse
 
maoxoam profile image
maoXoam

with many thanks

Collapse
 
iversonlv profile image
iversonLv

Thanks for the detailed explanation of such confusing knowledge.
Looking forwards to more such visualization tut and the best part is demonstrating with real-world cases for us.
Thanks.

Collapse
 
whoisyeshua profile image
whoisYeshua

@lydiahallie, looks like markup broken

Collapse
 
kkyler profile image
Khai

Great explanation! Your visualizations are the best :D

Collapse
 
srikanth597 profile image
srikanth597

everything looked good, except that symbol part

Collapse
 
kuro091 profile image
Kuro091

I'm sure many have asked before but why not just for each and then break; ?

Collapse
 
qadeer profile image
Qadeer Mangrio

a lot of learning