Friday, September 11, 2015

Generator Functions - New in Node 4.0.0

On Wednesday I wrote about arrow functions, a more concise syntax for anonymous functions that is now available in Node 4.0.0. But the new Node has many more new features! Another of the most interesting and useful additions is generator functions.

Generator functions are special functions which can be exited and then re-entered while maintaining their context. That means their variable bindings are saved across entrances. Their name comes from the ability to use these functions to produce sequences of values, like an Iterator in Java.

Generator functions are declared with the special function* syntax, and contain in their bodies a yield statement. Calling a generator function does not execute the body, but instead returns an iterator object which can be used to invoke the body. The statements in the body will be executed until the yield is reached, at which point control returns to the caller.

Consider this example code, which uses a generator function to print out the first 20 numbers in the Fibonacci sequence.

function* fibonacci(){
    var a = 0;
    var b = 1;
    var c = 1;
    while(true) {
        yield c;
        c = a + b;
        a = b;
        b = c;
    }
}

var gen = fibonacci();

for (var i = 0; i < 20; i++) {
    console.log(gen.next().value);
}

It might not be the most efficient way to generate Fibonacci numbers, but it's a good illustration of a generator. When gen.next() is called for the first time, the fibonacci function body is executed up to the yield statement on line 6. All subsequent calls to gen.next() pick up at the next line (seven), which happens to be inside the while loop. After changing the values of the internal variables, we're back to the yield again. This sequence of steps repeats every time gen.next() is called.

As you may notice, calling .next() actually returns on object with a value property. The value property contains whatever was yielded.

Generator functions can come in handy, but since they are part of the ECMAScript 2015 standard, or ES6, they aren't universally available yet. They've just come to Node. Use in the browser is limited to the latest Chrome and Firefox, which means that you're probably going to want to limit yourself to the server-side if you intend to incorporate them in your code.

But as my frogs have learned, being on the cutting edge can be less dangerous than living in the past.

Amphibian.com comic for 11 September 2015