Codementor Events

What are these things called generator functions* ?

Published Jan 07, 2020Last updated Jul 04, 2020
What are these things called generator functions* ?

In this lessons, we are going to explore one really great new ishhhh that was introduced into the javascript ecosystem and native to javascript now, moreover we most times say that its a function that resembles async/await

Fun Fact — Async Await is actually built on generators 😆

Now don’t get me wrong its not exactly ASYN / AWAIT its got almost a different flare to it, but its very similar in the sense that in async / await functions we AWAIT our Asynchronous events (our promised based events) where we pause the execution inside of our Asynchronous whenever we see the await call.

Well, our generator functions are very similar in the sense that they also pause their executions whenever they see a specific key inside of their function and that key is called a yield. now in other, for us to use this or achieve this there is a special syntax we actually have to declare our old school way of defining our function decorator but this time with a star beside it like this.

//codes here  
function* gen(){  
  // code goes here  
}

Now let's get to understand these things better, let's declare two console.log’s and see something here

//codes here  
function* gen(){  
  console.log('Hello There');  
  console.log('I am a generator'); 
}   
// Now i'd declear my gen function to a const  
const gfunc = gen() 
// this would return undefined    
//when i call gfunc in the console i get these weird suspended and they are called a generator object  
/* gen {<suspended>} __proto__: 
Generator [[GeneratorLocation]]: 
VM275:1 [[GeneratorStatus]]: 
"suspended" [[GeneratorFunction]]: ƒ* gen() 
[[GeneratorReceiver]]: Window [[Scopes]]: Scopes[3] 
**/

Now I know you might be a lot surprised at what's happening and why it's not doing our regular function executions where we would see our logs and all, but here is what we do on it, we call a .next() on it, and what .next() does is that I would resume the execution inside of our function, so at the point where we invoked it for the first time we instantiated this generator object that actually is aware of the code inside of our function but the execution inside of the gen() function is paused.
I know this might be a lot but it's easy what we do, in other to resume this function we just call the .next() on the gfunc const so until we call .next() on our function might not be able to run the execution

gfunc.next()
//Now this returns some things I want you to take note of   
Hello There I am a generator   
{  value: undefined,   done: true }

Now we get our log and an additional object and this object contains our value prop and a done property, now the done property tells us if there is any code to still run and in our case, there is none so we get true. now lets clear this up and go into something a bit advance

function* gen(i){  
   yield i;   
   yield i + 5; 
}  
cosnt gfunc = gen(5)

so now what we have done is that we have a gen() function that takes in I as an argument and then we yield the argument we parse in, and the argument plus 5 then we declared a const and gave it a value of 5. are we good? YES! so when we call a gfunc.next() let's see what we get.

gfunc.next()
//returns 
{
    value: 5, 
    done: false
}

so now we see that the value property in the object is the initial yield we mapped in the function and the done is false, why? now that's because we are not done playing our execution in the function meaning that there is more in the function it only paused after our first yield, now let's see what happens when we do .next() again

gfunc.next()
//returns 
{
    value: 10, 
    done: false
}

now we see that the value property in the object now contains our updated value and our done property is still false, now this is because in our yield function we never declared a return value and this is required so our generator function can know when to stop the execution. so now if we add a return value we see that our done returns true like this

function* gen(i){ 
   yield i; 
   yield i + 5; 
   return 20; 
}
cosnt gfunc = gen(5)
// first execution
gfunc.next()
//returns 
{
    value: 5, 
    done: false
} 
//second execution
gfunc.next()
//returns 
{
    value: 10, 
    done: false
} 
//final execution 
gfunc.next()
//returns 
{
    value: 20, 
    done: true
}

Now you see that we have our done value as true after the execution is done. this is primarily the base use of generator functions if you want to stash multiple executions but you want to control when you want to pause and play the execution. think of it as

An ability to pause functions

I think we should stop here for now. so the key thing you need to remember is, wherever we see yield that means our code is paused at that point even if its an Asynchronous code just like async / await.

I know that we have spent a lot of time talking about generator functions but then if you don't still understand, you can go over the article over and over again or I’d but in some great resources to aid your learning. see you in my other articles 😊

Discover and read more posts from Adenekan Wonderful
get started
post commentsBe the first to share your opinion
Jayen Ashar
3 years ago

what is “cosnt”? should it be “const”?

Shandy Sulen
4 years ago

You may wish to proof-read your article a bit more or send it to a friend or coworker for editing before posting :)

Veerabhadreshwara Poorma
4 years ago

I tried the same, and gfunc.next() gives result as :
(10,false) then (15,false) and (undefined, true)

Show more replies