Generators are function execution contexts that can be paused and resumed. When you call a normal function, it will likely return a value; the function fully executes, then terminates. A Generator function will yield a value then stop but the function context of a Generator is not disposed of (as it is with normal functions). You can re-enter the Generator at a later point in time and pick up further results.
function* threeThings() {
yield 'one 1';
yield 'two 2';
yield 'three 3';
}
let tt = threeThings();
console.log(tt);
console.log(tt.next());
console.log(tt.next());
console.log(tt.next());
console.log(tt.next());
console.log(tt); // {}
console.log(tt.next()); // { value: 'one', done: false }
console.log(tt.next()); // { value: 'two', done: false }
console.log(tt.next()); // { value: 'three', done: false }
console.log(tt.next()); // { value: undefined, done: true }
Iterator
An object is an iterator when it knows how to access items from a collection one at a time, while keeping track of its current position within that sequence. In JavaScript an iterator is an object that provides a next() method which returns the next item in the sequence. This method returns an object with two properties:done and value.
We can replicate the Generator example using just an Iterator:
function iterator(array) {
let idx = 0;
return {
next: () => {
return idx < array.length ? {
value: array[idx++],
done: false
} : {done: true};
}
};
}
let it = iterator(['one', 'two', 'three']);
console.log(it);
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
Generators are to a sequence of future values as Promises are to a single future value. Both Promises and Generators can be passed around the instant they are generated (even if some eventual values are still resolving, or haven't yet been queued for resolution), with one getting values via the next() interface, and the other via the then() interface.