Understanding ES6 Generators

In my attempt to keep on top of the newest features coming to the land of JavaScript, I will be writing a series of posts about the features that most interest me. Not that all of them aren’t interesting, but some are super awesome.

Generators are not an entirely new concept to the world of computer science and I had some previous familiarity with them in Python. Generator functions are defined by MDN as:

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.

Let’s take a step back and talk about a regular function. As we know it a function accepts arguments and executes until it either reaches a return statement or some sort of exception. Also in JavaScript we have a special case where we don’t provide a return statement and the function will implicitly return undefined (but that’s not worth diving into in this post).

A generator function gives us the opportunity to have freedom from the typical function protocol and return a series values. In essence this enables us to suspend (yield) our function for any given amount of time that we want and return several different values throughout the series of executions. The astute reader may think, “Well this is just an iterator”, and that would be correct.

Ok enough blabbering, lets look at some actual code (thanks to this post for a great first example):

function * foo() {
  for (var i = 0; i < arguments.length; i++) {
    yield arguments[i];
  }
}

So the first thing you should notice is the * between the function keyword and the function name foo. This is how we tell the JavaScript engine that this is a generator function. The second thing to take note of is the yield keyword in side of the loop. This special keyword will suspend the function in time, until you tell it to move forward. This can be done as follows:

var bar = foo(1, 2, 3);

bar.next(); // => Object {value: 1, done: false}
bar.next(); // => Object {value: 2, done: false}
bar.next(); // => Object {value: 3, done: false}
bar.next(); // => Object {value: undefined, done: true}

Quick side note on syntax: Like many things in JavaScript, the way that your format your syntax is entirely up to you (see: semi-colon wars).

With that said you have a couple of options when defining a generator function: function* foo(), function * foo() and function *foo(). Do what makes most sense to you and stick with it.


A generator function comes with a couple of methods including next, next is used to proceed throughout function. As you can see above, when we call the next method, it returns an object with a property of what is yielded and the state of the generator with a done property. Initially we are given the first value and the done property set to false, then the following and so on.

Finally when the generator has completed it will provide you with no value and the done property is now true.

This is just a basic overview of generators and there is ton more to learn about them. I will probably end up following up this post with several others to go into more detail and actual real-world examples of how you can utilize them.

Hope this helps as a introduction and I suggest checking out these several resources below as well:

 
95
Kudos
 
95
Kudos

Now read this

Hoisting

One of the tricky concepts that stumps newcomers to JavaScript is hoisting. Even seasoned developers coming from other languages can be bitten by this feature. In most C based languages developers are used to the concept of block based... Continue →