Introduction to Generators in ES6

With ES6, we were given a new tool: generators. In a normal function, there is only one entry point: the invocation of the function itself. A generator allows you to pause the execution of a function and resume it later. Generators are useful when dealing with iterators and can simplify the asynchronous nature of Javascript.

Syntax

So, how would we define a generator, compared to a normal function? You declare a generator function by using the * ( asterisk ) operator after the function keyword:

function* awesomeGenerator(){
  //code
}

To pause the execution inside the generator, we use the statement yield:

function* awesomeGenerator(){
  yield 'Hey friend' // We pause the execution here
  console.log('Back again') // When we resume, we are here
}

next() method

A generator gives you a next() method, which is used to start/resume the execution. This method returns an object with two keys:

{
  value: [ yielded value ],
  done: [ true if we reach the end]
}

Let’s see a very simple generator in action:

function* groceriesGenerator(){
  yield 'Eggs'
  yield 'Tomatoes'
  yield 'Milk'
  return 'Paper Bag'
}

const groceries = groceriesGenerator()

console.log(groceries.next()) // [1]
console.log(groceries.next()) // [2]
console.log(groceries.next()) // [3]
console.log(groceries.next()) // [4]

// [1] { value: 'Eggs', done: false }
// [2] { value: 'Tomatoes', done: false }
// [3] { value: 'Milk', done: false }
// [4] { value: 'Paper Bag', done: true }

At our first groceries.next() call, our groceriesGenerator reached our first yield statement and paused, returning the value Eggs to the caller. Our second next() resumed the execution at the second yield statement, pausing it again and returning Tomatoes

Our last next() terminates the generator, returns Paper Bag and sets done to true.

As iterators

In the introduction, I said that generators could help to implement iterators. Let’s see an example:

function* iterationGenerator( arr ){
  for( let i = 0; i < arr.length; i++ ){
    yield arr[i]
  }
}

const iterator = iterationGenerator( ['John', 'Sarah', 'Joe', 'Emily'])

let current = iterator.next()

while( !current.done ){
  console.log( current.value )
  current = iterator.next()
}

// John
// Sarah
// Joe
// Emily

In this example, you can see how the state of the generator is maintained accross invocations. Whne we resume the execution by calling next(), the variables and loops are the same.

Pass values back to generators

Finally, you can also pass a value back to a generator. Here is a example:

function* twoWayGenerator(arr){
  for( let i = 0; i < arr.length; i++ ) {
    const symbol = yield 
    console.log(`${arr[i]} ${symbol}`)
  }
}

const prices = twoWayGenerator([10, 23, 12])

prices.next()
prices.next('€')
prices.next('£')
prices.next('$')

// 10 €
// 23 £
// 12 $

Here, our first next() will not print anything because we pause the execution before the first console.log. The second next() is called with an argument. This argument is provided as the returned value of the yield statement. We store this value inside the symbol variable and use it next.

You can also force a generator to throw an error:

prices.next()
prices.throw( new Error('Invalid Amount'))

//  const symbol = yield
//                   ^
//  Error: Invalid Amount

That’s it for a quick and dirty introduction about generators. In the next article, we will go a bit deeper and explore how generators can help us control the asynchronous flow of Javascript.

9 Comments, RSS

  1. Louann October 22, 2017 @ 4:43 am

    Some truly interesting points you haqve written.Helped me a lot, just what I was searching for :
    D.

  2. old macdonald had a farm November 9, 2017 @ 7:26 pm

    What’s up, just wanted to say, I liked this blog post.
    It was inspiring. Keep on posting!

  3. Johnie November 15, 2017 @ 1:38 am

    Excellent post. Keep writing such kind of info on your page.
    Im really impressed by your blog.
    Hello there, You’ve done a great job. I will definitely digg it and personally recommend to my friends.

    I am sure they’ll be benefited from this site.

  4. Vilma January 2, 2018 @ 3:48 am

    Great goods from you, man. I’veunderstand your stuff
    previous to and you’re just too magnificent. I really like what you
    have aacquired here, really like what you’re stating and the way in which you say it.
    You make it entertaining and you still take care of to keep
    it sensible. I cant wait to read much more from you. This is really a great website.

  5. agen sbobet January 4, 2018 @ 3:24 am

    Hi there, I enjoy reading through your article post.
    I like to write a little comment to support you.

  6. Your way of describing the whole thing in this article is
    truly good, all can simply understand it, Thanks a lot.

  7. where can i buy with bitcoin February 8, 2018 @ 7:05 am

    Thanks for a marvelous posting! I genuinely enjoyed reading it, you are a great author. I will remember to bookmark your blog and will come back from now on. I want to encourage one to continue your great work, have a nice day!|

  8. reading plus story answers level i February 15, 2018 @ 4:20 pm

    I like reading through an article that will make people think.
    Also, thanks for allowing me to comment!

  9. cosplay costumes March 8, 2018 @ 7:20 am

    I don’t even know how I ended up here, but I thought this post was great.
    I do not know who you are but definitely you’re going to a famous blogger if you aren’t already 😉 Cheers!

Your email address will not be published. Required fields are marked *

*