Generators

Don't fear the *. The generator function specifies what value is yielded next time next() is called. Can either have a finite number of yields, after which next() returns an undefined value, or an infinite number of values using a loop.

function* greeter() {
                        yield 'Hi';
                        yield 'How are you?';
                        yield 'Bye';
                    }
                    
                    const greet = greeter();
                    
                    console.log(greet.next().value);
                    // 'Hi'
                    console.log(greet.next().value);
                    // 'How are you?'
                    console.log(greet.next().value);
                    // 'Bye'
                    console.log(greet.next().value);
                    // undefined

And using a generator for infinite values:

function* idCreator() {
                    let i = 0;
                    while (true) yield i++;
                }
                
                const ids = idCreator();
                
                console.log(ids.next().value);
                // 0
                console.log(ids.next().value);
                // 1
                console.log(ids.next().value);
                // 2
                // etc...