Javascript Generators: A Beginner's Guide
Tags: javascript, beginners, webdev, tutorial
Published: 2022-11-03 23:59:17

Recently, I’ve had to pick up some JavaScript concepts to better reaffirm my understanding before moving on to work with them in React, and Generators was one of those concepts I had some little unrest understanding. I decided to piece together the basics to serve as a beginner’s working guide to generators.

## Introduction: What are Generators?
According to the [MDN resource](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*)

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

Generator functions are similar to regular functions, except that they can be paused and resumed. Generators are also very closely related to iterators, in the sense that a generator object is an iterator.

## Comparison; Generators and Functions
A regular function such as the one below cannot be stopped before it finishes its task i.e. its last line is executed. It follows something called the [run-to-completion](https://en.wikipedia.org/wiki/Run_to_completion_scheduling) model.

```
function regularFunction() {
  console.log('There')
  console.log('is')
  console.log('no')
  console.log('stopping')
  console.log('me')
}
```
The only way to exit the `regularFunction` is by using a `return` statement or throwing an error. If you call the function again, it will begin the execution from the top again.

In contrast, a generator is a function that can stop midway and then continue from where it stopped. See the illustration below;

![Functions vs Generators](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mebzdogaxiktr41gtn6e.png)

## Syntax
Generator functions are created using a special syntax by adding an * after the `function` keyword just like this `function *`, and can be paused using the `yield` keyword.

Calling a generator function initially does not execute any of its code; instead, it returns a generator object. Code is only executed and values are returned only when the generator’s `next() ` is called, which then executes code until it encounters the `yield` keyword, upon which it pauses, until `next()` is called again.

```
function * createGenerator() {
  yield 'This';
  yield 'is';
  yield 'a';
  yield 'Generator';
}
const generator = createGenerator(); // assigning the Generator function to the generator constant
generator.next(); // { value: 'This', done: false }
generator.next(); // { value: 'is', done: false }
generator.next(); // { value: 'a', done: false }
generator.next(); // { value: 'Generator', done: false }
generator.next(); // { value: undefined, done: true }

```
Calling `generator.next()` repeatedly after our last statement above will only `return` (or more accurately, `yield`) the same `return` object: `{ value: undefined, done: true }`.

## Generators in Action

### Looping through an Array:
Using a `for of` loop we can iterate over our generator and `yield ` the content at each loop.

```
// create an array of animals
const animalsList = ['Cat', 'Dog', 'Monkey', 'Bird', 'Fish'];

// create our looping generator
function* loop(arr) {
  for (const item of arr) {
    yield `I like a ${item} as a pet`;
  } 
}

const animalGenerator = loop(animalsList);
console.log(animalGenerator.next());
// Object { value: "I like a Cat as a pet", done: false }
console.log(animalGenerator.next());
// Object { value: "I like a Dog as a pet", done: false }
console.log(animalGenerator.next().value);
// "I like a Monkey as a pet"
```

Our generator will now loop over the array and print one value at a time every time we call `.next()`, To get only the value, then use `.next().value` and it will not print the status of the generator.

### `.return()` in Generators
With `.return()` we can return a given value and finish the generator.

```
function* animalsList(){
  yield 'Cat';
  yield 'Dog';
  yield 'Monkey';
}

const animals = animalsList();

console.log(animals.return());
// Object { value: undefined, done: true }
```
We got `value: undefined` because we did not pass anything in the `return()`.

## Summary
It’s not often you need generators. This article is just to provide a basic explanation of javascript generators. There is much more you can do with a generator, You can check out the official [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) for more advanced cases where the use of generators can come in handy.