# Generators

* Generators are the function that can be paused and resumed
* Defined using \* after function keyword
* yield to pause a generatore optionally pass back some value
* are used with iterators
* return an iterator when invoked
* next() method resume generator
* can pass value to iterator using next('my value')

**Note**

we have to install "babel-polyfill" to use this feature with webpack

```
// in webpack.config.js add below entry
// entry: ['babel-polyfill', './main.js'],
```

## Generator Demo

```javascript
function* generateMe(){
    yield "One";
    yield "Two";
    yield [1,2,3];
}

var generator = generateMe();
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());

// Output
// { value="One",  done=false}
// { value="Two",  done=false}
// { value=[3],  done=false}
// { done=true,  value=undefined}
```

## Use generator for dependent API calls

/search/man -> /users/123 -> /photos/233

```javascript
function ajax(url){
    return fetch(url).then(res => res.json()).then((data)=> stepGen.next(data));
}

function* steps(){
    const users = yield ajax('https://reqres.in/api/users');
      console.log(users)
    const user = yield ajax('https://api.github.com/users/hs950559');
      console.log(user);
    const posts = yield ajax('https://reqres.in/api/posts');
      console.log(posts);
}

const stepGen = steps();
  stepGen.next();
```

## Loop over generators ( use for of loop )

```javascript
function* steps(){
    const users = yield 'https://reqres.in/api/users';
    const user = yield 'https://api.github.com/users/hs950559';
    const posts = yield 'https://reqres.in/api/posts';
}

const stepGen = steps();

for(const val of stepGen){
    console.log(val);
}

// output
https://reqres.in/api/users
https://api.github.com/users/hs950559
https://reqres.in/api/posts
```

## Demo - Now i know my abc

```javascript
function* abcGenerator(arr){
    for(var i=0; i<arr.length; i++){
        yield arr[i];
    }
} 

var gen = abcGenerator(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);

var abc = setInterval(function(){
    var letter = gen.next();

    if(letter.done){
        clearInterval(abc);
        console.log("Now I know my abc");
    } else {
        console.log(letter.value);
    }
}, 500);
```
