The full video and many others like it are all available as part of our Frontend Masters subscription.

Kyle Simpson

Kyle Simpson is an Open Web Evangelist from Austin, TX, who's passionate about all things JavaScript. He's an author, workshop trainer, tech speaker, and OSS contributor/leader.

Kyle Simpson

You Don't Know JS

Generators are coming in ES6. A generator is a new type of function that can be paused during execution and resumed at a later time. The are paused using the yield keyword.

Get Unlimited Access Now

Kyle Simpson: So, how could we do something completely different? How could we solve this problem in a completely different way. Again, remember the problem, the solution we're driving towards, is to attempt to express asynchronous looking code in a synchronous looking fashion. Okay? And I'm going to introduce to you this concept called generators, it's coming as of ES6+, so it's this brand new thing that's been invented.

It breaks an assumption that you have had about your JavaScript code from the beginning of time. There's something new, a whole new invariant that is broken that we've never known before. You may not have even known that you could assume this, but it is true that we assume as soon as a function starts executing the first line of its code, we assume that it will finish all of those lines of code before any other piece of code runs.

Kyle Simpson: That's called the run to completion invariant of JavaScript. We assume that it can never be interrupted and paused and come back. That's true of all normal functions. It's not true of generators. We now have a new type of function that can literally pause itself right in the middle of the function and could be resumed later.

And that's what are called generators. This is going to bend your brain a little bit but just stick with me. We have this new syntax for function declarations, which is function*. Those of you that have, by the way, that have dealt with function*, you know that's supposed to be function pointer, so that should drive you nuts that they chose function star for the syntax, but that's what they chose.

So this is our generator syntax. And it looks like a normal function except it has this new keyword in it called yield that we see there on line 3. Now, what is a generator going to do? You see on line 7, I execute the function, or at least it looks like I execute the function, when I call it.

But I actually haven't executed anything about the function when I call it. And that's what's different about generators. When you call a generator function, it actually constructs an iterator for you. So what I get back is an iterator. You guys probably know what iterators are. You can call next on them to step through a data set or something.

This constructs an iterator to control the operation of our generator. So when I call on line 7, when I call gen, I actually haven't executed any of this code yet. On line 8 when I call, I start up the generator on line 2 and I run until it comes to the next yield statement, and then it pauses itself right there in the middle of the function, and it returns control back to this part of the program.

At some later time like the next statement or 5 years from now, I can call again and it will resume from where it paused, and it will run either to the end or to the next yield statement. So a generator can pause itself and then an iterator can resume it.

And it can pause itself and an iterator can resume it and it can start and stop an infinite number of times. It's a function that doesn't even have to ever complete, actually. And that's a new weird thing that we've never seen before. This is a new capability. And you might ask yourself, why on earth?

This just seems crazy. How on earth could this actually help? We'll get there. I promise. I'm going to skip over the coroutine. That's just a little bit of extra complexity that we don't need. But if I wanted to run my generator what I'm doing here is on the first statement I'm going to say one plus yield null.

Now, when I yield null I'm actually taking the null value I'm I'm yielding it out. So yield is actually a message passing mechanism. It's actually a two way message passing mechanism. We can pass messages into our generator, and receive messages back from our generator. So, it's kind of crazy.

So, what's actually going to happen with this code, is when I run the run function right here, it's going to start up my code, and it's going to come to this first yield, and it's going to give me out a null value. So, that null value will be the return value of that first run call.

At some later time, I can then say run(10) and when I say 10, the value 10 is passed in as the expression result of the yield expression. So 10+1 will then be assigned to x and x will be 11. It will keep going. It'll say var y=1+, i see another yield.

I better pause. So it'll yield out another null. That null will come back as the returned value of this function call. At some later time, we then can say run 30, which is going to pass in 30 as the return result of that expression. 30+1 is equal to 31.

We now have x+y, 11+31 is 42 we yield the 42 value out as the return result of this function. So it's a two way message passing mechanism.
Kyle Simpson: I know it still looks confusing trust me. I'll show you in just a moment why this helps with asynchronicity.
Speaker 1: This is not asynchronous right?

This looks more
Kyle Simpson: I'm about to show you the asynchronicity. That was all synchronous but now I'm about to show the asynchronously. Now we're going to introduce the idea that my steps don't synchronously iterate. So right here when I say var x=1 +, I'm going to yield out, but I'm going to call a function which is not going to immediately iterate.

It's going to wait 1,000 milliseconds before it iterates. So, look at this code. Does this code look synchronous to you? It looks very synchronous. You could write a test suite like this. Here's my test one and test two and assert this and assert that but actually underneath the covers this code will start and stop asynchronously.

And that's the true power of generators solving asynchronous flow control because it gives us a perfectly synchronous looking syntax. But it allows us to hide the asynchronicity behind the scenes, okay? A generator can iterate synchronously, but it can also iterate asynchronously. And that's the power of this mechanism.

Generators are a whole brand new thing. There's all kinds of complexity that we haven't even begun to scratch the surface on. I would venture a guess that I'm going to be back here in 3 or 4 years and I'm going to be teaching you a new class and I'm going to be talking about generators and everybody's going to be like, of course generators.

Why we would ever have done promises or call backs? But it's too new right now. We're still scratching the surface on what generators are going to be like. In fact, there's a new thing that they're even thinking about already for ES7 which is an abstraction on top of generator.

So there's all kinds of exploration going. I'm giving you a glimpse into what the future of asynchronous JavaScript programming is going to start to look like. You can see how this is drastically different than the way we deal with callbacks and nested inversion of control. Yeah?
Speaker 2: Do you see a problem with promises and those new generators, where they may intermingle a use in the field?

Kyle Simpson: Actually, the future is that promises and generators are going to work together.
Speaker 2: Got you, okay.
Kyle Simpson: Yeah, so right now we're not using promises here. But the future is that we'll yield out a promise and it'll come back when it finishes. That's already something that we'll see that in just a moment, that's already something you can do but I think that's the most likely path to the future, is where the two work together.

Those will be called async functions, by the way. So that's coming in ES7 probably.

Ready to take your code to the next level?

Intense courses with world-class teachers and unlimited access to our growing library of videos for the great price of $39 per month.

Get Unlimited Access Now