But now, after a few years of seeing generators in the wild and using them in my code, it’s time to answer the big question.
Do you need to learn generators?
Before I get to the big secret … two secrets, really … it’s important to understand what generators are which informs why they are so important.
What Is A Generator?
Ok, enough computer science lessons… what is a generator, really?
A generator will halt execution of a function for an indefinite period of time when you call “yield” from inside a function.
The code that invoked the generator can then control exactly when the generator resumes… if at all.
And since you can return a value every time execution halts (you “yield” a value from the function), you can effectively have multiple return values from a single generator.
That’s the real magic of a generator – halting function execution and yielding values – and this why generators are so incredibly important, too.
But a generator isn’t just one thing.
There’s 2 Parts To A Generator
There’s the generator function, and the generator iterator (I’ll just call that an iterator from here on out).
A generator function is defined with an * (asterisk) near the function keyword or name. This function is responsible for “yield”-ing control of its execution – with a yielded value if needed – to the iterator.
An iterator is created by invoking the generator function.
Once you have an iterator, you can … you guessed it, iterate over the values that the generator function yields.
The result of an iterator’s “.next()” call has multiple properties to tell you whether or not the iterator is completed, provide the value that was yielded, etc.
But the real power in this is when calling “it.next();” the function will continue executing from where it left off, pausing at the next yield statement.
This means you can execute a method partway, pause it by yielding control to the code that made the function call, and then later decide if you want to continue executing the generator or not.
For more detail on this, I’ll list some great resources for what generators can do, below.
Right now, though, you should know about the real value and power of generators: how they make async functions a possibility.
Secret #1: Async Functions Use Generators
In fact, with generators and promises alone, you can create async/await functionality on your own.
It’s true! I’ve written the code, myself. I’ve seen others write it. And there’s a very popular library called co (as in coroutines) that will do it for you.
Compare that to the same async function calls using the syntax you saw yesterday.
With only a few minor syntax changes, co has written the same level of abstraction in calling asynchronous methods that look synchronous. It even uses promises under the hood to make this work, like async functions.
Clearly there was influence from this ingenuity in co, that influenced the final specification of async/await.
Secret #2: You Don’t Need To Learn Generators
Async functions are built on the same underlying technology as generators. They encapsulate generators into what co provided for you, as a formal syntax instead of a 3rd party library.
But do you need to learn generators?
Make no mistake. You absolutely need generators.
Without them, async functions wouldn’t work. But you do not need to learn how to use them, directly.
They’re complex, compared to the way you’ve been working. They aren’t just a new way to write iteration and asynchronous code. But they represent a fundamental shift in how code is executed, and the API to manage that is not how a developer building line-of-business applications wants to think.
Sure, there are some use cases where generators can do really cool things. I’ll show you those in the resources below. But your code will not suffer one iota if you don’t learn how to use generators, directly.
Let the library and framework developers deal with generators to optimize the way things work. You can just sit back and focus on the awesomeness that is async functions, and forget out generators.
One Use Case For Generators
Ok, there is one case where I would say you do need generators.
If you want to support semi-modern browsers or Node.js v4 / v6 with async/await functionality…
And if you can’t guarantee the absolute latest versions of these will be used… Node v7.6+, MS Edge 15, Chrome 57, etc…
Then generators are your go-to option with the co library, to create the async function syntax you want.
Other than that, you’re not missing much if you decide to not learn generators.
So I say skip it.
Just wait for async/await to be readily available and spend your time learning promises instead (you absolutely need promises to effectively work with async functions).
In spite of my advice that you don’t need to learn generators, there are some fun things you can do with them if you can completely wrap your head around them.
It took me a long time to do that.
But here are the resources I used to get my head into a place where generators made sense.
And some of my own blog posts on fun things I’ve done with generators.