Have you seen a generator before? If not, I suggest you to really focus on this post. Generators are a really helpful feature in Javascript. They allow you to run asynchronous code as synchronous code as well as many other things.

Generators allow you to run asynchronous code as synchronous code, among other things…

Generators

What does function* means?

First, let me show you how a generator looks like…

function* generatorFunction() {
	// do something
	yield someValue
}

Wow! What’s that, right?

Is not as complicated as it looks, but before talking about generators specificaly, we need to understand something called Iteration Protocols.

Iteration protocols in Javascript

Iterable protocol, symbol iterator in array
Iterable protocol, symbol iterator in String native
Execution of Symbol.iterator()
Plain object without iterator

Methods to work with iterators

Now it’s time to talk about some native methods we can work with, in order to get the data inside the object. Let’s see some of them:

For of method over iterable
Spread operator over iterable

Generators: What are they?

Finally, let’s see what a generator function is, and how can we use it as part of the iterator protocols in Javascript.

A generator is a function that can be started or paused for the programmer who is writing the generator. It’s execution returns an object that complies with the iterator protocol.

Easily, a generator is a function that returns an iterable. As every iterable on Javascript, it has the next method to iterate over the data, and the done boolean to know when we’ve reach the latest item of the dataset.

We can define a generator as a sugar sintactic way to write iterators.

Let’s check the syntax again:

function* generatorFunction() {
	// do something
	yield someValue
}

What do we have here? Let’s go step by step.

First, we have a function* sentence. As you can imagine, this reserved word function with the asterisk at the end is just to tell the interpreter that here we don’t have a regular Javascript function, but a generator.

Then we have the generator’s name, nothing weird there. Is just to provide a name to the function, in order to call it later.

But inside the body of the generator, what do we have there?

Yield? What is that about?

Yield is a reserved word in Javascript, used only inside generator functions. Generators wouldn’t be as powerful if it wasn’t for the yield word.

When we see a yield instruction like the one in the example, we have to know that our function execution will stop on that word, and the interpreter will return us the value to the right of the yield.

Yield is a word you just can use inside a generator.

Well, we can combine this knowledge to say that every time we run the next() method of a generator, it will stop on a YIELD command and return whatever value we want.

Iterator object by generator function

In a generator function you can have as many yield commands as you want. All of them will define the amount of times you can execute the next() method on your iterator object.

Iterator object by generator function, multiple yields

Next() method with parameters

Now you may wonder, can we pass parameters to the next() method? Well, to answer that we can do some kind of exercise. First, let’s assign a yield command to a variable, inside our generator function.

Assign yield value to variable

Anyone looking at this code may think that yield command is being assigned to fromSecondNext variable. But what is truly happening is that the yield command will stop the execution and return the value at the right of the command.

Running next on iterator from previous generator

This way, the second execution of next() command will assign anything we pass as parameter into the fromSecondNext variable.

Once we run the command, the second yield will return the argument passed.

Passing value as parameter on next

This may seem a bit useless if we see this basic example, but if we think about the possibility of working with the parameter inside the generator function, the utilities are infinites.

Nesting generator functions

Let’s say we have a really big generator, and we want to do some refactoring over it, in order to clarify and improve the code.

Let’s say now that we need to split our big generator into multiple generators, and then start calling them in a secuencial order, just to replicate the previous big generator.

We can totally do this, by using the y_ield*_ command. This command is very similar to the y_ield_ command, but is only used to call another generator inside a generator. Let’s see an example:

Nesting generators

This way we have a better code, with a decoupled logic in each one of our generators.

Now, let’s picture we want to call our gen2 function, from another place. We only need to do

Calling decoupled generator from elsewere

And this way we can easily call a generator with params.

Calculating factorial with a nested recursive generator

Let’s play a bit, just for fun. Let’s build a generator that will help us to find a factorial of any number.

Factorial: the results of multiplying all the previous numbers of an specific natural number.

Example: 4! === 4*3*2*1 === 24
The factorial of 4 (4!) is 24.

Factorial with generator

Do you think you understood generators? That’s great! Could you write an example like this one, but showing the fibonacci sequence on it?

Fibonacci: starting with cero and one, the following number is the result of adding the previous two numbers.

WARNING! The result of previous task is below…

Fibonacci with generators

And that’s it! We’ve reached the end of the article about generators and iteration protocols!
I hope this information was util for you, and you have learned a bit about this very interesting topic in Javascript.

Thanks for reading it!