Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Ecma 1
  • Overview
  • Transcript

5.2 Generators

Generators are a new type of function, related to iterators, that can yield a (possibly infinite) series of return values. Let's learn how to pass values in to generators, and then see what comes out.

5.2 Generators

Hi, folks. In this lesson, we're going to look at another new type of function in NES6, a generator function. This new type of function is powerful, and has been generating huge amounts of interest in the developer community, because it's so different from regular JavaScript functions. Defining a generator function is really easy, we still use the function keyword but we add an asterisk directly after it. In almost all respects, it's just like a regular function. It can have a name and can accept parameters. With a regular function however, once it starts, it executes all of the statements it contains and then returns all further activity of the function stops until it is invoked again. This behavior is known as run to completion. Generator functions on the other hand do not run to completion. They can return a value, pause, and then resume sometime later where they left off. And continue processing sometimes returning many values before they end. Regular functions are blocking. While they are running no other code can run. With generator functions we can pause them, and this allows other code to run. The way that we pause a generator is with the new yield keyword. We can use yield by itself, or we can use it to return value, a bit like the return keyword. And like with the return keyword, if we don't specify a return value it will return an implicit undefined. So for this example, let's return the square of the perimeter. And just so you can see that the generator does pause after this statement, let's add a console log after it. Another difference between regular functions and generator functions is that we don't actually invoke generator functions like we do a regular function. We invoke the generator in order to get an iterator. And it is the iterator that actually invokes the generator. We still need to pass the parameter to the generator when we invoke it to get back the iterator. We looked at iterators in the last section and saw that they should have a next method. In order to invoke the generator function then we invoke the iterator's next method. So, this makes the function run to the first viewed expression which will produce a value and return an object. As with any other iterator, the object returned after invoking the next method will contain a value parameter and a done parameter to indicate whether the next method can be invoked again. You'll notice that we haven't seen the console log and, as you can guess, the reason is because the generator is currently paused on the yield statement which appears before the logs statements. In order to see the log statements, we need to invoke next again. The generator resumes execution when we invoke the next method again and prints the log to the console. This time in the object returned by the next method, the value is undefined and the done parameter is true. One of the key points of the example so far is how we can pass a value back from the generator with the yield expression. But what about sending new values into the generator? This is also possible and is another fundamental aspect of generators. Let's make a couple of changes to the example code. First of all, we can save the results of the first yield to a new variable. We wrap the original yield expression in parentheses and then multiply this by x again. We can also log y to the console at the end. We use the next method to pass values into the generator when we resume it. The value we pass in will be inserted into the generator as the result of the previous yield statement. So this time let's parse ten into the second call to the next method. Let's go back to the browser now and see what happens. We see that the first time the generator is invoked with the next method, everything works as it did before. The parameter we parsed in originally is squared. And this is the value that is passed back by the next method. The second time we invoke it, however, we pass in the value 10. And this is inserted into the generator inside the parentheses. When the generator resumes, the calculation is therefore 10 multiplied by x, to give the value for y that we see in this second console log. As well as using yield, we can also return at the end of the generator and when the iterator for the generator is used with the next method, the value returned will be set as the value property in the object returned by the next method. Another point to note is that a value passed to the next method the first time the next method is used is discarded and is not available inside the generator. The reason for this is because the generator hasn't yet evaluated a yield expression the first time that it gets invoked. So, in this lesson we learned about generator functions, and saw that they are a new and powerful type of function in ES6 that can be paused and resumed instead of running to completion and blocking other code. We saw that we define a generator using the star character after the function keyword. We learned that to pause a generator we use the yield keyword, and that we can pass back a value using a yield expression. We also saw that generator functions are used with an iterator. We invoke the generator once to get its iterator and then use the iterators next method to start or resume the generator. We also saw that we can pass values into a generator when resuming it using the next method. And that these values will be inserted as a result of the yield expression, the generator paused out previously. Thanks for watching.

Back to the top