Hold Up - What Are JavaScript Generators?
Braydon Coyer / July 16, 2021
4 minute read
•
--- viewsWe learned JavaScript knowing that functions execute from top-to-bottom, just like we read English from left-to-right. That all changed when ES6 was released in June of 2016, bringing with it the ability to pause functions in the middle of execution.
How does this work? Generators! Also known as Generator Functions.
A generator function can be paused at any given point and continue where it left off when told to do so. Pretty crazy, right?
Let's take a look at a basic example.
Generator functions in JavaScript are created much like any other function, except for one difference in syntax. Can you spot it?
1function* tacoIngredients() {2 yield 'Shell';3 yield 'Meat';4 yield 'Lettuce';5 yield 'Cheese';6}
The difference is in the function definition itself - generator functions are written using the function*
syntax.
You probably noticed the yield
keyword in the example above. When a generator function is called, it executes until it encounters a yield
expression. At this point, the generator function pauses, returns the value defined after the yield
keyword, and waits to continue execution until the function is called again.
Here's another difference between Generators and regular functions in JavaScript: generator functions return its value in a wrapped object. Why? Because technically, Generators conform to the Iterator protocol (think Maps and Observables), which means the wrapped object looks like this:
1{2 value, // the next value you want to get from the generator function3 done; // a flag informing you if this is the last value in the sequence4}
If we wanted to get the data in the tacoIngredients
function defined in the example above, it would look something like this:
1function* tacoIngredients() {2 yield 'Shell';3 yield 'Meat';4 yield 'Lettuce';5 yield 'Cheese';6}7
8const taco = tacoIngredients();9
10console.log(taco.next()); // { value: 'Shell', done: false }
Each time we call the next()
method, an object is returned in the shape mentioned prior. To get the data, simply access the value
property. Because the done
property has a value of false, we know there is more data to be retrieved and we can call the generator again.
1function* tacoIngredients() {2 yield 'Shell';3 yield 'Meat';4 yield 'Lettuce';5 yield 'Cheese';6}7
8const taco = tacoIngredients();9
10console.log(taco.next()); // { value: 'Shell', done: false }11console.log(taco.next()); // { value: 'Meat', done: false }12console.log(taco.next()); // { value: 'Lettuce', done: false }13console.log(taco.next()); // { value: 'Cheese', done: false }14console.log(taco.next()); // { done: true }
If we call next()
after the generator has encountered its last yield
keyword, it returns an object with a single property - and it's probably what you're expecting - done
is set to true!
JavaScript Generator Functions are really cool - and I hope this article helped you understand how to use them in your own projects!
Want a real-world example? Here's a CodePen demo I made that calculates the Fibonacci sequence using JavaScript Generator Functions!
Thanks for reading! If you enjoyed this article, consider sharing it on Twitter and signing up for my developer newsletter below so you don't miss out on my future content!
Cover photo by Chris Dickens / Unsplash
Articles delivered to your inbox!
A periodic update about my life, recent blog posts, how-tos, and discoveries.
As a thank you, I'll also send you a FREE CSS tutorial!
No spam - unsubscribe at any time!