Playing around with ES6 Generator

August 4, 2015

I’ve heard a lot of people talking about the new ES6 feature generators. I’ve read a couple of post about them, but none have really talked about what they are really good for (or at least I haven’t found any really good examples), or rather, most have blogs have had pretty bad examples, like controlling application flow with generators, which I’d say isn’t the best of ideas.

First a little about Generators, this is what MDN has to say about them.

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

Calling a generator function does not execute its body immediately; an iterator object for the function is returned instead. When the iterator’s next() method is called, the generator function’s body is executed until the first yield expression.

Mozilla Developer Network on Generator

So in essence it’s a function that returns, nay yields its results. And when you’re done with the results, no matter how much time has passed, you can pick up from where you started.

The thing where I really think it shines, is with endless algorithms or sequences. Most people know about the fibonacci sequence. Invented by the Italian mathematician Fibonacci in 1202. The sequence starts with 1 (or 0), and each subsequent number is the sum of the previous two (1, 1, 2, 3, 5, 8, 13, etc.).

It’s also a popular programming interview question, since it usually tests recursive logic.

Anyway, the sequence is endless, so if you try to generate the numbers without a ceiling, you’ll end up in an infinite loop, it will never end. And that’s where I think Generators are the perfect solution.

/**
 * Runs through the fibonacci sequence with as many numbers
 * as specified in the parameter.
 */
function *fibonacci(numbers) {
	var prevValue = 0;
	var currentValue = 1;
	var newValue = 0;
	for(var i = 0; i < numbers; i++) {
		newValue = currentValue+prevValue;
		prevValue = currentValue;
		currentValue = newValue;

		yield currentValue;
	}
}

// Go through the 10 first numbers in the sequence
for (var v of fibonacci(10)) {
	console.log( v );
}

I’m guessing you spotted that I’ve actually sent in the value 10, that I only want to iterate the sequence for 10 steps. The neat thing is that you can send in Infinity to the function, and the generator will output the next value for all eternity.

// Or manually fetch items for as long as you want
var fib = fibonacci(Infinity);

console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
console.log(fib.next().value); // 3
console.log(fib.next().value); // 5
console.log(fib.next().value); // 8
console.log(fib.next().value); // 16
[.....]
console.log(fib.next().value); // 573147844013817200000

Or bind it to a setInterval which spits out the next value every 1 seconds.

var fib = fibonacci(Infinity);

setInterval(
	function() {
		console.log(fib.next().value);
	},
	1000
);

Anyway, it’s a neat function, I don’t think I’ll use it too much, but it’s nice knowing it’s there.

Tags