Generators in ECMAScript 6

Monday, February 16, 2015

You’ll know you are looking at a generator, or more properly, a generator function, because a generator function contains an asterisk in the declaration.

function*() {

}

Once you have a generator function, you can use the yield keyword inside to return multiple values to the caller.

let numbers = function*() {

    yield 1;
    yield 2;
    yield 3;
};

But, the numbers don’t come back to the caller all at once. Internally, the runtime builds an iterator for you, so a caller can iterate through the results one by one. You can write a low level iterator and call next to move through each value, or use a for of loop.

let sum = 0;

for(let n of numbers()) {
    sum += n;
}

expect(sum).toBe(6);

Going back to the classroom class we used in the last ES6 post, we can now make a classroom an iterable simply using yield.

class Classroom {

    constructor(...students) {
        this.students = students;
    }

    *[Symbol.iterator]() {
        for(let s of this.students) yield s;
    }
}

var scienceClass = new Classroom("Tim", "Sue", "Joy");

var students = [];
for(let student of scienceClass){
    students.push(student);
}

expect(students).toEqual(["Tim", "Sue", "Joy"])

Notice how the iterator method needs an asterisk before the opening square bracket. The syntax is quirky, but an asterisk is always required when defining a generator function, because generator functions need to behave differently than normal functions right from the start. That’s the topic for the next post in this series.


Comments
gravatar Matt Tuesday, February 17, 2015
Good overview! I agree, the syntax is quirky (and that's putting it nicely!), but I'm very glad to see this in JavaScript. I've been a big user/abuser of 'yield' in C#, so I'm glad I can finally do the same thing in ES6. :)
Comments are closed.

My Pluralsight Courses

K.Scott Allen OdeToCode by K. Scott Allen
What JavaScript Developers Should Know About ECMAScript 2015
The Podcast!