Hold Up - What Are JavaScript Generators?
Tags: webdev, javascript, tutorial, programming
Published: 2021-07-16 14:56:42

_This article was originally posted [on my blog](https://braydoncoyer.dev/blog/hold-up-what-are-javascript-generators/)_

We learned JavaScript knowing that functions execute from top-to-bottom, just like we read English from right-to-left. 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.

## Creating a JavaScript Generator Function

Generator functions in JavaScript are created much like any other function, except for one difference in syntax. Can you spot it?

```js
function* tacoIngredients() {
  yield 'Shell';
  yield 'Meat';
  yield 'Lettuce';
  yield 'Cheese';
}
```

The difference is in the function definition itself - generator functions are written using the `function*` syntax.

## The JavaScript Generator Yield Keyword

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.

## Returning Values from JavaScript Generator Functions

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:

```js
{
  value, // the next value you want to get from the generator function
    done; // a flag informing you if this is the last value in the sequence
}
```

If we wanted to get the data in the `tacoIngredients` function defined in the example above, it would look something like this:

```js
function* tacoIngredients() {
  yield 'Shell';
  yield 'Meat';
  yield 'Lettuce';
  yield 'Cheese';
}

const taco = tacoIngredients();

console.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.

```js
function* tacoIngredients() {
  yield 'Shell';
  yield 'Meat';
  yield 'Lettuce';
  yield 'Cheese';
}

const taco = tacoIngredients();

console.log(taco.next()); // { value: 'Shell', done: false }
console.log(taco.next()); // { value: 'Meat', done: false }
console.log(taco.next()); // { value: 'Lettuce', done: false }
console.log(taco.next()); // { value: 'Cheese', done: false }
console.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!

## Wrapping Up

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!

{% codepen https://codepen.io/braydoncoyer/pen/vYOOobg %}


### Resources

- [Understanding Generators in ES6 JavaScript with Examples](https://codeburst.io/understanding-generators-in-es6-javascript-with-examples-6728834016d5)
- [A Simple Guide to Understanding Javascript (ES6) Generators](https://medium.com/dailyjs/a-simple-guide-to-understanding-javascript-es6-generators-d1c350551950)
- [JavaScript Generators](https://www.javascripttutorial.net/es6/javascript-generators/)

Thanks for reading! If you enjoyed this article, consider sharing it on Twitter and signing up for my [developer newsletter](https://braydoncoyer.dev/newsletter/) so you don't miss out on my future content!

_Cover photo by Chris Dickens / Unsplash_