Generators in Javascript ES6

Yoel Macia
The Javascript Adventure
3 min readDec 14, 2019

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.

Let’s talk about having a function that prints the letters of the alphabet.

This function will execute all console.log() from top to bottom and we cannot stop it or interact with it in this time period.

Unless the function:

1. Throw some error.
2. Return something.

So how do we for example interact with those internal values of the function while executing? Can we stop and continue executing where we want ?

We can do it with,

Generators

When introducing generators we have to talk about three concepts.

  1. Function* ()
  2. Generator Object
  3. Yield

Function*()

The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.

This type of functions are only differentiated from normal functions by the asterisk (*), which tells us that it is a generator function.

So let´s create our generator function,

Calling a generator function does not execute its body immediately; an generator object for the function is returned instead.

Generator Object

The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.

So let´s call our generator object

But why is returning a Object [Generator] {} and not a value?

Because we are not calling the function*, to do it we need to add .next() to our generator.

But now how do we interact with those console.logs within the function?

With the third concept of our generator, yield.

Yield

The yield keyword is used to pause and resume a generator function (function* or legacy generator function).

Yield can only be called directly from the generator function that contains it. It can't be called from nested functions or from callbacks.

Let´s add yield to our example,

We see that the first console.log() is executed and then the function stops in yield. Returning the execution outside the function. For example running another console.log() with the string “after”.

We can also return a value with the yield out. But we need to call value when we call the .next() function such that way.

Why an object?

Because .next() method return an Object with two properties:

value -> Any Value.

  • value - any JavaScript value returned by the iterator. Can be omitted when done is true.

done -> Boolean.

  • Has the value true if the iterator is past the end of the iterated sequence. In this case value optionally specifies the return value of the iterator.
  • Has the value false if the iterator was able to produce the next value in the sequence. This is equivalent of not specifying the done property altogether.

--

--

Yoel Macia
The Javascript Adventure

Writing daily about Javascript. Creator of the publication The Javascript Adventure.