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.
OdeToCode by K. Scott Allen