Check out a free preview of the full ES6: The Right Parts course:
The "Generators" Lesson is part of the full, ES6: The Right Parts course featured in this preview video. Here's what you'd learn in this lesson:

A generator is a function that can be started and stopped through the use of an iterator. The yield keyword indicates where the function should pause and what value should be returned at that pause. A done property is returned along with the yielded value to indicate if the function has finished running.

Get Unlimited Access Now

Transcript from the "Generators" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Kyle Simpson: We're going to come back to this example in just a moment and rewrite it. But I want to take a quick little detour and talk to you about the last feature that I'm going to introduce to you today, which is called a generator. Now, I do not have time to fully explain all that happens with generator, so I'm going to give you kind of a short cut explanation and strongly encourage you go do some more reading about them.

[00:00:24] I've got several blog posts out there. They're covered in two of my books. Strongly recommend you read a lot more about generators. So, I'm not gonna fully explain all the whys and hows of it, cuz that would take another several hours. I'm just gonna quickly introduce them to you, so we can see how they can be useful.

[00:00:41] Generators look like this. We put the star there and then we give it some kind of name. Doesn't have to be a name could be anonymous, but generators need that star there. Now, what's interesting about a generator, if I just have something silly like this. What's interesting about a generator is that when I call it, that code doesn't actually run, the way we're used to functions running.

[00:01:06] What happens is that calling the generator doesn't execute its code. What it does, is it constructs an iterator. And it stays in a pause state and then it says, you can use the iterator to control the generator. The generator is a function that can be started and stopped as many times as you'd like.

[00:01:33] You can start it and it pauses, and start it again, and it pauses, and start it again and pause it. So, in this particular case nothing is run, but if I call it.next, It's going to print out, Hello, and the it.next call here is going to return us a iterator result, that's going to have value undefined done true, because the generator is all complete.

[00:02:04]
>> Kyle Simpson: But what if I wanted to pause the generator somewhere. Well now, I can use a special new keyword that's only valid inside of generators called yield. The yield keyword says to pause. Literally only locally inside of the generator, not the whole program, just inside of the generator, it just pauses at that point.

[00:02:26] So, I could have this.
>> Kyle Simpson: And the result object here would have been { value: undefined, done: false }. Because at this moment we are paused right here, and we're not yet done. And then later any time, I feel like I could call it.next again.
>> Kyle Simpson: What's going on?

[00:03:01] I could call it.next and I'd get, again, { value: undefined,
>> Kyle Simpson: done: true }. If I did something like return 10; here, that value 10 would be right here. And if I did something like yield nine, that value would show up right here. So, the yield keyword is not just a way to pause, but it's also a way to send a value out while the function is still running.

[00:03:36] You following me?
>> Kyle Simpson: [COUGH] What do you think would happen if I said?
>> Kyle Simpson: What's gonna happen?
>> Speaker 3: Zero, nine, zero ten.
>> Kyle Simpson: So, remember how the ten value comes back with done true, and remember how the iterator consumers, think whenever they see done true, they just stop and don't do anything else.

[00:04:23] So, if we run this code. What we're going to see, is just nine. We printed out the hello world, but the just nine. We don't see the ten, right? For that reason we don't see the 10, because the for loop said, done true and it threw away any value that might have gotten back out.

[00:04:41] So, if you wanted that 10 value to be there. What would you change this to?
>> Speaker 3: Yield, the yield.
>> Kyle Simpson: Now, all of a sudden we'll get both of those values out.
>> Kyle Simpson: Okay? The point that I'm making is, a generator can yield out as many values as you want it to.

[00:05:04] Here, I'm doing it manually, but what if I did something like this.
>> Kyle Simpson: Now, what's going to happen? I'm gonna yield out the values zero, one, two, three and four.
>> Kyle Simpson: Okay. So, let me take a step back for just a moment and let you kind of digest that.

[00:05:53] What I'm going to say here is not going to make a lot of sense completely, because we really don't have time to get into all of these generators. But if you want to understand what a generator really is. It's a state machine.
>> Kyle Simpson: Every time we pause and then unpause, we're just moving from one state to the next state, to the next state.

[00:06:15] So, it's a function that keeps going menu. It keeps remembering its current state, because it's pausing and then when you unpause it moves to the next state, and then it pauses again, and then it keeps going and keeps going. So, because it's a state machine, it also has a really easy way to model producing values.

[00:06:34] That's kind of the reason it has that name generator, because it generates values.
>> Kyle Simpson: You with me? And the cool part about a generator is, that it automatically does all the work of producing that iterator interface for us, we don't have to do any of that manual crap next methods, or iterator results or anything.

[00:06:54] We just simply yield out values and it all works.
>> Kyle Simpson: Yes.
>> Speaker 4: In a nutshell, I know you said in more details, that in terms of the stock where that generates, or place where he waits for one deal to the other deal.
>> Kyle Simpson: Under the covers, this four of loop is calling dot next to each time.

[00:07:22] So, the generator pauses, when it gets to a yield keyword, sending out a value if you yield something. And it just waits forever until somebody calls dot next again. The four of loop the dot, dot, dot operator they automatically consume an iterator to completion. Meaning they will just keep calling a dot next on that iterator, until they get out done true.

[00:07:46] The generator will return done true, once it gets to the end, and does a return.
>> Speaker 4: Can I say this is kinda expensive operation to process, or something like that. I just keep reminding a while true forever.
>> Kyle Simpson: Absolutely, that's entirely legal. You could have something like this, unique ID, while true yield math.random.

[00:08:23]
>> Kyle Simpson: Every time in your code that you want to new unique ID, you just say, numbers.next().value. And every time you call it, it will just give you a new one, give you a new one.
>> Kyle Simpson: Generators never have to finish if you don't want them to. They're what we call lazy sequences, which is a whole other separate thing, but.

[00:08:51]
>> Kyle Simpson: [COUGH] The key idea that we want to get here is that you can yield out a number. You can yield out any value that you want. So, this could be looping over the results that you have from a database query, and just yielding out a new row every time.

[00:09:05] That's one way of consuming database results and adapting them to an iterator.