ES6 (ES2015) - Generators

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 10 years ago
Updated 6 years ago

Generators in ECMAscript 6 are first-class coroutines that produce encapsulated suspended execution contexts. Whew! Yield values and iterate over them until no more values exist in the generator. We'll talk more about practical use later ;)

You make a generator by adding asterisks right here after the function keyword. I'll go ahead and add a log statement saying that you called next. You might think that if I called greet that it would log out you called next but nothing happens.

If we assign something like a greeter to this greet and then we see what the greeter is you can see that the greeter is actually an object so it did not invoke this. It actually created an object which I can call next(on). When I call greeter.next, and I'll just call this next and log that out. You can see that next is undefined and done true.

You can also see that it finally invoked our log statement saying that you called next. Now, this is undefined because we didn't yield anything from our generator. It's done because it's gone through all of the yield statements which are actually none right now.

If I yield a simple hello and run this again you can see now I get value hello and done false. It logged out our statement. It returned hello and it's not done yet. It will actually be done on the next pass through next.

If I call next again, and I'll just name this one done, and I call the log statement again, so I'll just log out done. You can see that I get hello on the first pass with done as false and undefined with done as true because there are no more yield statements after this one, meaning it had iterated and gone through all of the yield statements.

If you have multiple yield statements like how, are, and you and you run this with only calling next once you can see that it stops after calling how. This is not called. That's not called, and that's not called.

If you were to create any objects or anything inside of here they would not be created until you called next, meaning that you can put stuff in here that's not created until you explicitly need it.

If we go ahead and call next three more times and run it again you can see it logs out each log statement, then the yield, the log, then the yield. It logs this, then yields that, then logs this, then yields the next one.

Because it's an iterator you can also use the for/of syntax. We can say for word of greeter and then log out the word and then run that. You can see the output is basically the same. "How are you?" The main difference is that this is grabbing the value off of the next.

To do that by calling next we'd have to revert this and say .value, then run it again and we get the same output.

It's really easy to get mixed up when you start assigning things to yield statements. If I say let friendly equal yield how and then I try to log out friendly you might expect it to log out how because that's what it's yielding. But if I run this you'll see it's actually logging out undefined.

The way that this works is that the next step through the iteration, so if I say "The heck," will basically send this back through and assign it to this friendly. If I log this out now you'll see I get "How," and then "The heck." That means you can start building things through the iteration process.

If I yield friendly+r and then I assign friendly to this and then I yield friendly+u and I pass in silly ole and I run this again you can get "How the heck are silly ole you?" because this message is being returned here when the next step is run and assigned to this friendly. I yield that part of the friendly and then this comes from here, which is being assigned here. Then it yields that final statement.

One thing to note is that because this assignment happens on the run after the first one it's actually impossible to pass a value in here. If I try and say first and run this I'll get an error saying, "Sent value to a newborn generator," because you haven't given this a chance to run and iterate and go to the next step where you could actually pass in a value.

Lastly, generators also help you work with infinite sequences. If I wrap my yield with a wild true, which is never going to stop looking, I can safely yield this X and Y point knowing confidently that this stuff isn't going to evaluate until the next step through after the yield process.

It will safely pause instead of infinitely going through this while loop. When I run this, you can see I get zero, two, four, six, eight and so on. Zero, one, two, three, four, and so on. I could generate these forever. They're also only created when I request them through the yield. They're not created ahead of time.

Don't worry. We will dive more into practical use cases of generators in future videos.

Saiful
Saiful
~ 9 years ago

This may sound off topic, but up until this video, i've noticed that ecma script 6 looks a lot like python.. any reason or story behind it?

James
James
~ 9 years ago

I was following along with the ES6 lessons nicely up to this one. Then........wat?

Bress B
Bress B
~ 9 years ago

John Lindquist mentions there will be follow up lessons on practical use cases of Generators. I realize there are whole courses on RxJS, etc but can we see some practical uses of Generators soon?

James
James
~ 9 years ago

John Lindquist mentions there will be follow up lessons on practical use cases of Generators. I realize there are whole courses on RxJS, etc but can we see some practical uses of Generators soon?

I'm wondering the same thing. There is an RxJS Observables + Generators lesson by Mr. CycleJS.

Michael Hueter
Michael Hueter
~ 8 years ago

I was following along with the ES6 lessons nicely up to this one. Then........wat?

same

James Bedont
James Bedont
~ 8 years ago

lost the thread of the course on this video. I really could have used some sort of practical example of generators.

Joel Hooks
Joel Hooks
~ 8 years ago

lost the thread of the course on this video. I really could have used some sort of practical example of generators.

Hey James, generators had me scratching my head for a practical use for a long time. Then I saw them used for redux-sagas. Mind blown! http://joelhooks.com/blog/2016/03/20/build-an-image-gallery-using-redux-saga

DANIEL Pride
DANIEL Pride
~ 8 years ago

Please fix this sound. Twelve is very low volume, then when you come into thirteen it blows your eardrums out !!!

Chris Pauley
Chris Pauley
~ 7 years ago

I would also like to see practical use cases of generators.

Gabriel
Gabriel
~ 7 years ago

At 4:38, when I called the first next with a string, it didn't throw a TypeError for me.

CrazyFunker
CrazyFunker
~ 7 years ago

does anyone have a link to his aforementioned 'practical uses' video? cheers

Alex
Alex
~ 7 years ago

there's a course for generators you might like to watch https://egghead.io/courses/write-simple-asynchronous-code-with-javascript-generators

CrazyFunker
CrazyFunker
~ 7 years ago

there's a course for generators you might like to watch https://egghead.io/courses/write-simple-asynchronous-code-with-javascript-generators

Thanks Alex!

Reinart Geronimo
Reinart Geronimo
~ 6 years ago

I agree with many of the comments above that this chapter is missing information on practical use cases for generators.

Marek Zeman
Marek Zeman
~ 6 years ago

Finally a simple explanation of generators. So far I was just confused about the logic and usage. Thanks!

Markdown supported.
Become a member to join the discussionEnroll Today