JavaScript: what are generators (yield)
Tags: javascript, generators, yield
Published: 2021-01-12 07:13:50

First of all, what the heck does **yield** mean? As a non-native English speaker, I found it very confusing. So based on  [Cambridge Dictionary](https://dictionary.cambridge.org/dictionary/english/yield) and  [Macmillan dictionary](https://www.macmillandictionary.com/dictionary/british/yield_1), **yield** is:
> **To produce something useful such as information or evidence**
>
> "*Knowing about our past does not automatically yield solutions to our current problems.
yield results/benefits: The search for truth is beginning to yield fruitful results.*"
>
> "*A letter found by the FBI last week may yield new clues.*"


So, now that we know what the word means, let's talk JavaScript.

**Generators** are a kind of *special* function that can stop its execution midway and start again from the same point where it stopped after some time. They are basically a combination of  [functions](https://developer.mozilla.org/en-US/docs/Glossary/Function)  and [iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).

When you call a generator, it returns an object `{value: value, done: true|false}`, where **value** is the value to be *yielded* and **done** is a Boolean that tells the generator if `.next()` function will yield a value or *undefined*.

To create a generator function we need to use the `*`: 
```javascript
function* generator(i){ ... }
``` 
This is because `*` tells JavaScript that an iterator object is going to be returned and unlike regular functions, it doesn't start its execution straight away.

Let's have a look at how to use generator functions:
```javascript
function* generator(i) {  
	yield i + 10;
	yield i + 20;
	yield i + 50;
}

const generate = generator(15);

console.log(generate.next()); // {value: 25, done: false}
console.log(generate.next()); // {value: 35, done: false}
console.log(generate.next()); // {value: 65, done: false}
console.log(generate.next()); // {value: undefined, done: true}
```

When we call the `next()` function the execution starts. It executes until it finds the first `yield` statement and yields the value. When called again, `next()` will resume the generator function until it finds the next `yield` statement and this cycle ends when there are no more `yields`, finishing with `{value: undefined, done: true}`.

A `return` statement in a generator will make the generator finish its execution (like any other function), setting the `done` property `true` and all other `yields` after the `return` will be `undefined`:

```javascript
function* generator(i) {  
	yield i + 10;
	yield i + 20;
	return;
	yield i + 50;
}

const generate = generator(15);

console.log(generate.next()); // {value: 25, done: false}
console.log(generate.next()); // {value: 35, done: false}
console.log(generate.next()); // {value: undefined, done: true}
```

The same applies if an error is thrown: the following `yields` will all be `undefined`.

You can also yield another generator function by using `yield*`: 

```javascript
function* func1() {
  yield 73;
}

function* func2() {
  yield* func1();
}

const iterator = func2();

console.log(iterator.next()) // {value: 73, done: false}
console.log(iterator.next()) // {value: undefined, done: true}
```

### Advantages
- **Lazy loading**: it evaluates the value only when there's need for it.
- **Memory efficient**: as we only evaluate values when needed, less memory for storing those values is needed.

### Risks
- Generators don’t provide random access like arrays and other data structures.
- Generators provide one-time access. So you can't iterate through the values again.

### Why use generators
I honestly didn't find any use cases for my own code. Researching the internet, I found an interesting article on dev:  [Use-Cases For JavaScript Generators](https://dev.to/rfornal/use-cases-for-javascript-generators-1npc).

### Using JavaScript generators to optimize APIs
 [IROEGBU!](https://hashnode.com/@iroegbu) wrote an amazing post about using generators to optimize APIs, you can check it [here](https://iroegbu.com/using-javascript-generators-to-optimize-apis).

### Sources
- [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)
- [freeCodeCamp](https://www.freecodecamp.org/news/yield-yield-how-generators-work-in-javascript-3086742684fc/)