JavaScript generators are possibly one of the most poorly understood portions of the incoming ES6 JavaScript specification, at least they are for me. In this post, you’ll learn about generators (as they are in JavaScript) from a really quick “what the heck are these” level, with some links at the end if you want more.
What’s a generator and why do I care?
Generators are reusable and pausable functions.
You care because generators are a New Thing™ in JavaScript, plus they’re useful for creating custom iterators and doing asynchronous JS. In these 3 minutes, you’ll learn about making a custom iterator (text parser), but async is something that requires a little more time.
How do I write one?
You will need:
- function*
- yield or yield* (yield* is only if you want to yield another generator. Moving on!)
A simple generator:
function* Greetings() {
yield "hello"
yield "hola"
yield "bonjour"
}
To create an iterator object from your generator, call it:
var greeting = Greetings()
The generator hasn’t spit out any values yet, that happens when you call next
on the
generator like so:
greeting.next() // hello
greeting.next() // hola
greeting.next() // bonjour
greeting.next() // undefined
Each instance of a generator is read-once so once we’ve called next enough, it’s done. Try clicking the “Run generator” button in this JSBin and see what comes out in the console, paying special attention to the “done” value.
What about a more complex example?
In JavaScript, it’s pretty common for us to parse text. With a generator, we can write a text parser that gives us an object we can either step through at will (calling .next()
), or we can loop through the generator to see it all happen at once. This parser is cool, because we could feed it different strings and get a new generator when we want one.
Here’s the code that, given a string, returns each word, except if there’s a phrase in quotes, which we decided (because reasons) that we want as a single value. In the JSBin, you can click on the button to have it run through the generator all at once, using another ES6 feature, the for .. of
syntax.
N.B. our parser isn’t very smart, so it’s not going to handle quotes other than “, or escaped quotes, or what have you, but doing that is very possible.
Where can I learn more?
Learn more about ES6 generators at:
- MDN (documentation! whoo!)
- ES6 Generators in Depth with Dr. Axel Rauschmeyer, a great in-depth look at this data structure
- You Don’t Know JS: Performance, Chapter 4 (Generators) with Kyle Simpson, more advanced, on using generators in asynchronous code.