# Mixing Generators Into Iterators

A relevant ad will be displayed here soon. These ads help pay for my hosting.
You can support Pony Foo directly through Patreon or via PayPal.

As it turns out, iterators can be written using generators. This can lead to some interesting use cases. Read on to understand the synergistic properties between these two JavaScript iteration concepts.

Let’s do a quick recap of generators (read our primer on generators here). Generator functions return generator objects when invoked. A generator object has a `next` method, which returns the next element in the sequence. The `next` method returns objects with a `{ value, done }` shape.

The following example shows an infinite fibonacci number generator. We then instantiate a generator object and read the first eight values in the sequence.

``````function* fibonacci() {
let previous = 0
let current = 1
while (true) {
yield current
const next = current + previous
previous = current
current = next
}
}
const g = fibonacci()
console.log(g.next()) // <- { value: 1, done: false }
console.log(g.next()) // <- { value: 1, done: false }
console.log(g.next()) // <- { value: 2, done: false }
console.log(g.next()) // <- { value: 3, done: false }
console.log(g.next()) // <- { value: 5, done: false }
console.log(g.next()) // <- { value: 8, done: false }
console.log(g.next()) // <- { value: 13, done: false }
console.log(g.next()) // <- { value: 21, done: false }
``````

Iterators follow a similar pattern (you may read our primer on iterators here). They enforce a contract that dictates we should return an object with a `next` method. That method should return sequence elements following a `{ value, done }` shape. The following example shows a `fibonacci` iterable that’s a rough equivalent of the generator we were just looking at.

``````const fibonacci = {
[Symbol.iterator]() {
let previous = 0
let current = 1
return {
next() {
const value = current
const next = current + previous
previous = current
current = next
return { value, done: false }
}
}
}
}
const sequence = fibonacci[Symbol.iterator]()
console.log(sequence.next()) // <- { value: 1, done: false }
console.log(sequence.next()) // <- { value: 1, done: false }
console.log(sequence.next()) // <- { value: 2, done: false }
console.log(sequence.next()) // <- { value: 3, done: false }
console.log(sequence.next()) // <- { value: 5, done: false }
console.log(sequence.next()) // <- { value: 8, done: false }
console.log(sequence.next()) // <- { value: 13, done: false }
console.log(sequence.next()) // <- { value: 21, done: false }
``````

Let’s reiterate. An iterable should return an object with a `next` method: generator functions do just that. The `next` method should return objects with a `{ value, done }` shape: generator functions do that too. What happens if we change the `fibonacci` iterable to use a generator function for its `Symbol.iterator` property? As it turns out, it just works.

The following example shows the iterable `fibonacci` object using a generator function for its iterator. Note how that iterator has the exact same contents as the `fibonacci` generator function we saw earlier. We can use `yield`, `yield*`, and all of the semantics found in generator functions hold.

``````const fibonacci = {
* [Symbol.iterator]() {
let previous = 0
let current = 1
while (true) {
yield current
const next = current + previous
previous = current
current = next
}
}
}
const g = fibonacci[Symbol.iterator]()
console.log(g.next()) // <- { value: 1, done: false }
console.log(g.next()) // <- { value: 1, done: false }
console.log(g.next()) // <- { value: 2, done: false }
console.log(g.next()) // <- { value: 3, done: false }
console.log(g.next()) // <- { value: 5, done: false }
console.log(g.next()) // <- { value: 8, done: false }
console.log(g.next()) // <- { value: 13, done: false }
console.log(g.next()) // <- { value: 21, done: false }
``````

Meanwhile, the iterable protocol also holds up. To verify that you might use a construct like `for..of`, instead of manually creating the generator object. The following example uses `for..of` and introduces a circuit breaker to prevent an infinite loop from crashing the program.

``````for (const value of fibonacci) {
console.log(value)
if (value > 20) {
break
}
}
// <- 1
// <- 1
// <- 2
// <- 3
// <- 5
// <- 8
// <- 13
// <- 21
``````

This was a fun trick. What would you use it for in a real-world program?