What the... generators!
Tags: javascript, iterators, generators, loops
Published: 2018-05-06 08:49:40

---
title: What the... generators!
published: true
description: About generators in Javascript
tags: javascript, iterators, generators, loops
cover_image: https://thepracticaldev.s3.amazonaws.com/i/1rffpf8ccpzhv71ps6nv.jpg
---

Want to know about _generators_?

### FIRST you need to check [iterators](https://dev.to/genta/what-the-iterators-1lhc)

That's not something you can skip, because, generators work _through_ iterators. We can say that _generators_ are a simpler way to write our own iterators.

This is a _generator_:

```js

function* breeds(){
	yield "labrador";
  	return "chow-chow";
}

const iterator = breeds();

console.log(iterator.next())
//->{value: "labrador", done: false}
console.log(iterator.next())
//->{value: "chow-chow", done: true}
console.log(iterator.next())
//->{value: undefined, done: true}

```

Let's see what's happening here.

First, we need to create a _generator function_, and we can do that by using a _*_ between _function_ and the _function name_.
No matter if it's:
`function* breeds()`
`function *breeds()`
`const breeds = function *()`
`const breeds = function*()`
This will work anyway!.

(But, It's a _standard_ to use the _*_ just after the _function_ ... so try to always use the syntax `function*`.)

Inside that function we're using that _yield_ ... what's that?
_yield_ It's something listening to the _next()_ calls.

Everytime we use the _.next()_ on the iterator, the generator will use the _next not yet used_ yield.
That's the same _idea_ behind *iterators* and we're checking that, with the _done_ key the iterators returns!.

If It's value is _false_ the _.next()_ will call the _yield_ AFTER the previous one.


```js

console.log(iterator.next())
//->{value: "labrador", done: false}
console.log(iterator.next())
//->{value: "chow-chow", done: true}
console.log(iterator.next())
//->{value: undefined, done: true}

```

When the _done:true_ will happens?
When there's no more to _yield out_ that generator.

But we need to be more *precise* about this.

<center>![focus](https://media.giphy.com/media/YPiZm67MsCpCo/giphy.gif)</center>

We all know that a function, in JS, always returns something.
If you do not define a _return_, JS will do It for you, by _returning an "undefined"_ at the end of It.


```js

function* breeds(){
	yield "labrador";
  	yield "chow-chow";
}

const iterator = breeds();

console.log(iterator.next())
//->{value: "labrador", done: false}
console.log(iterator.next())
//->{value: "chow-chow", done: false}
console.log(iterator.next())
//->{value: undefined, done: true}

```

By taking away the _return_ from the function, calling _.next()_ will force JS to return a `{value: undefined, done: true}`

So JS still returns It for you, also with _generators_, because, we're still talking about functions here!

If you want to *force a return* you can use the _.return()_ method on the _iterator_ and finish the _generator_.

```js

function* breeds(){
	yield "labrador";
  	yield "chow-chow";
}

const iterator = breeds();

console.log(iterator.return("we <3 dogs"))
//->{value: "we <3 dogs", done: true}
console.log(iterator.next())
//->{value: undefined, done: true}
console.log(iterator.next())
//->{value: undefined, done: true}

```

As you can see, we're immediately _returning_ and finishing the generator with the _.return()_ method!.

##generators are not magic!

We're really not _executing_ stuff by calling the _generators_ ... indeed, we're using the _iterator_ interface every time we're calling _generators_ with the _.next()_ method.

We can see the _.next()_ as a remote controller to START (calling yield) and PAUSE (checking the _done:_ value) the _generator function_

That's why, we need to define:

```js

const iterator = breeds();


```

and call the `iterator.next()`

(_iterator_ It's just the variable name, not the _iterator object_ itself)

##lot of stuff can be done

In real life work, we can do really lot of stuff with _generators_.

We can use _generators_ values with variables.
We can _fetch_, _spread_ and use the _for...of_ loop.

At the moment we're using _generators_ to call one single _yield_ at time, we can say, that we're using It in _synchronous_ way.

But, generators can be also used in _asynchronous_ way.
I'm not going to cover It now... you can check about _Promises_ or _async/await_, and maybe, we we'll talk about that, another day.
[Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
[Async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) 

<center>HAVE FUN WITH CODE</center>


<center>![Pearl Jam](https://media.giphy.com/media/WOXeOKbVHcUG4/giphy.gif)</center>