Generators. What are they?

A man trying to explain what in the world a generator, as it relates to Javascript, is.
The man behind the generator. Ooohh....that's why async code works...

What is a generator?

Generators are declarative iterators that will be used more and more as Javascript matures. Why? Because, the comity behind Ecmascript is deciding to move more towards a declarative approach rather than an imperative approach to programming in Javascript.

Okay, but what are those terms...iterators...declarative...imperative?

Consider an array that you loop over using forEach() or a standard for loop, for instance.

Iterators are data structures that you loop over using for loops and variations of for loops (e.g. the forEach() method).

Declarative, means a type of programming where you tell the computer, "Do what I say, and you decide how it gets done".

Imperative, means a type of programming where you tell the computer, "Do what I say, exactly as I tell you to".

What this essentially means is that Javascript is going to have a larger library of code that programmers can use to make their lives easier. But, that ease of use will not have the same amount of power and freedom that comes with the more imperative way to program that is a bit more complex as well.

When Would I use generators?

You would use generators whenever you want to make your life easier by making your code easier to read and understand, when you are going over a data set like an array, set, map, or even objects ( they can be iterated over with custom code ).

Generators would also be used whenever you want more control over the flow of the iteration of your data. This is because with Generators, you can pause and resume execution according to the conditions that you specify.

Generators execute until they reach the yield keyword, and not necessarily the end of the length of a string or array, for example.

Examples of Generator Use

Modular Generator Methods

Generators are recognized by the use of an asterisk next to either the function keyword, or next to the name of the function.

My personal preference is to put the asterisk next to the name of the function, because whenever I invoke the function it will be easy to know if that function is a generator or not.

          
          function *numberIterator( start = 5, end = 25, step = 5 ) {
            let iterations = 0;
            for ( let i = start; i < end; i += step ) {
              iterations++;
              yield i;
            }
            return iterations;
          }
          
        

It's also a good idea to use destructuring for your parameters, so that it can be modular to use. Setting defaults are also not a bad idea, in regards to protecting yourself from logical errors (e.g. undefined values).

The yield keyword is what makes a generator special. It is used here to indicate that the execution will stop after iterations++ in this example. This helps keep the code a bit simpler by for instance, allowing you to declare yield i, instead of having an if statement there.

Iterating over objects

Objects are not an iterable data structure, but that doesn't mean we can't iterate over it. Which also means, we can use Generators to iterate over objects.

Here's an example:

          
            var properties = {
              name: "Sergio",
              hairColor: "black",
              eyeColor: "brown",
              *[Symbol.iterator]() {
                for( let i = 0; i < 30; i++) {
                  yield i;
                }
              }
            };

            for( let person of properties ) {
              console.log(person); //prints out [0, 1, 2, 3...29]
            }
          
        

What we are doing is creating a properties object, which has a name, hairColor, eyeColor, and a Generator as a property (remember the asterisk!).

Defining a generator within an object will then allow us to iterate over it using for loops; which is pretty awesome!

Lastly, I decide to iterate over the object and log out its properties with a for...of loop.

Summary

We learned that generators are a more declarative way to loop over our data, that generators provide a way to control when to pause and resume data iteration, and that Javascript is moving towards the declarative programming paradigm instead of an imperative paradigm.